文件操作工具
概述
这个模块提供了一组用于文件操作的实用工具函数,包括文件下载、内容导出为文件以及文件扩展名解析等功能。这些函数在前端应用中特别有用,可以帮助您处理文件相关的操作。
函数列表
1. 文件下载函数 - downloadFile
通过 XMLHttpRequest 请求下载文件并使用自定义文件名保存。
函数签名
typescript
function downloadFile(fileInfo: { url: string; name: string }): void参数
fileInfo: 包含以下属性的对象:url(string): 要下载的文件的URLname(string): 保存文件时使用的文件名
使用示例
javascript
import { downloadFile } from '@pt/utils/modules/file';
// 下载一个文件并重命名
downloadFile({
url: 'https://example.com/documents/report.pdf',
name: '2023年度报告.pdf'
});💡 所以你该传什么样的 fileInfo.name?
你应该传入你希望用户保存时看到的文件名,比如:
ts
downloadFile({
url: "https://example.com/files/data.csv",
name: "用户数据.csv",
});💡 补充:
- 如果名字中带中文,浏览器也能识别(不用 encode)
- 可以加后缀名(如
.png、.pdf),否则有些浏览器保存时可能变成无扩展名
工作原理
- 使用 XMLHttpRequest 发起 GET 请求获取文件内容
- 以 blob 形式接收响应数据
- 创建一个临时的
<a>元素并设置其 href 为 blob URL - 设置 download 属性为指定的文件名
- 自动触发点击事件下载文件
- 清理创建的 blob URL 以释放内存
2. 内容导出为文件 - exportFileFromContent
将字符串内容导出为文件,自动根据指定的类型选择合适的文件扩展名和 MIME 类型。
函数签名
typescript
function exportFileFromContent(
content: string,
type: string,
fileName?: string
): void参数
content(string): 要保存到文件中的内容type(string): 内容的类型,如 'html', 'javascript', 'python' 等fileName(string, 可选): 保存的文件名(不含扩展名)。如果未提供,将使用 "file-" 前缀加上随机 UUID
支持的文件类型
| 类型 | 扩展名 | MIME 类型 |
|---|---|---|
| html | .html | text/html |
| svg | .svg | image/svg+xml |
| vue | .vue | text/x-template |
| react | .jsx | text/jsx |
| javascript | .js | application/javascript |
| js | .js | application/javascript |
| python | .py | text/x-python |
| py | .py | text/x-python |
| typescript | .ts | application/typescript |
| ts | .ts | application/typescript |
| css | .css | text/css |
| scss | .scss | text/x-scss |
| sass | .sass | text/x-sass |
| json | .json | application/json |
| markdown | .md | text/markdown |
| cpp | .cpp | text/x-c++src |
| c | .c | text/x-csrc |
| java | .java | text/x-java-source |
| swift | .swift | application/swift |
| kotlin | .kt | text/x-kotlin |
| rust | .rs | text/x-rustsrc |
| mermaid | .mermaid | text/vnd.mermaid |
如果提供了不受支持的类型,将默认为 .txt 文件和 text/plain MIME 类型。
使用示例
javascript
import { exportFileFromContent } from '@pt/utils/modules/file';
// 导出 HTML 内容
const htmlContent = '<html><body><h1>Hello World</h1></body></html>';
exportFileFromContent(htmlContent, 'html', 'my-page');
// 将创建 my-page.html 文件
// 导出 JavaScript 代码
const jsCode = 'function greeting() { return "Hello World"; }';
exportFileFromContent(jsCode, 'js');
// 将创建 agentos-[uuid].js 文件
// 导出 JSON 数据
const jsonData = JSON.stringify({ name: 'John', age: 30 }, null, 2);
exportFileFromContent(jsonData, 'json', 'user-data');
// 将创建 user-data.json 文件工作原理
- 根据提供的类型确定适当的文件扩展名和 MIME 类型
- 生成包含随机 UUID 的文件名(如果未提供文件名)
- 使用内容创建一个 Blob 对象
- 创建一个临时的
<a>元素,设置其 href 为 blob URL - 添加元素到 DOM,触发点击下载,然后移除元素
- 释放创建的 blob URL
3. 解析文件扩展名 - parseFilenameSuffix
从文件名或 URL 中提取文件扩展名。
函数签名
typescript
function parseFilenameSuffix(fileUrlOrFilename: string): string参数
fileUrlOrFilename(string): 文件名或文件 URL
返回值
- 返回小写的文件扩展名(不含点),如果未找到扩展名则返回空字符串
使用示例
javascript
import { parseFilenameSuffix } from '@pt/utils/modules/file';
// 从文件名解析扩展名
const ext1 = parseFilenameSuffix('document.pdf');
console.log(ext1); // 输出: "pdf"
// 从 URL 解析扩展名
const ext2 = parseFilenameSuffix('https://example.com/files/image.PNG?v=123#section');
console.log(ext2); // 输出: "png" (转换为小写)
// 没有扩展名的情况
const ext3 = parseFilenameSuffix('README');
console.log(ext3); // 输出: "" (空字符串)工作原理
- 使用正则表达式匹配文件名或 URL 中的扩展名部分
- 正则表达式能够处理带有查询参数或片段标识符的 URL
- 将找到的扩展名转换为小写并返回
4. 从响应头解析文件名 - parseFileNameFromContentDisposition
从 HTTP 响应头的 content-disposition 中解析文件名。
函数签名
typescript
function parseFileNameFromContentDisposition(contentDisposition: string | null): string参数
contentDisposition(string | null): HTTP 响应头中的 content-disposition 值
返回值
- 解析后的文件名,如果未找到则返回空字符串
使用示例
javascript
import { parseFileNameFromContentDisposition } from '@pt/utils/modules/file';
// 从 content-disposition 中解析文件名
const fileName = parseFileNameFromContentDisposition('attachment;filename=report.xlsx');
console.log(fileName); // 输出: "report.xlsx"
// 从 URL 编码的 content-disposition 中解析文件名
const fileNameEncoded = parseFileNameFromContentDisposition('attachment;filename=综åˆåˆ†æž-差异分æžå¯¼å‡º.xlsx');
console.log(fileNameEncoded); // 输出解码后的文件名使用前提
后端需要在响应头中设置适当的 Content-Disposition 和相关配置:
java
// 后端配置示例 (Java)
response.setHeader("Access-Control-Expose-Headers","Content-Disposition");
String fileName = "example file.txt";
String encodedFileName = URLEncoder.encode(fileName, "UTF-8");
response.setHeader("Content-Disposition", "attachment;filename=\"" + encodedFileName + "\"");5. 带认证的文件下载 - fileDownload
使用 XMLHttpRequest 下载文件,自动添加认证 token,并从响应头中解析文件名。
函数签名
typescript
function fileDownload(url: string, fileName?: string | undefined, callback?: () => void): void参数
url(string): 文件的 URLfileName(string, 可选): 保存的文件名,如果未提供将尝试从 content-disposition 或 URL 中获取callback(function, 可选): 下载完成后的回调函数
使用示例
javascript
import { fileDownload } from '@pt/utils/modules/file';
// 下载文件,使用自动获取的文件名
fileDownload('https://api.example.com/download/report');
// 下载文件,指定文件名
fileDownload('https://api.example.com/download/data', '财务报表.xlsx');
// 下载文件,并在完成后执行回调
fileDownload('https://api.example.com/download/data', 'report.pdf', () => {
console.log('下载完成');
});工作原理
- 创建 XMLHttpRequest 请求,设置响应类型为 blob
- 从本地存储读取认证 token 并添加到请求头
- 发送请求获取文件
- 从响应头中解析文件名,或使用提供的文件名,或从 URL 中提取
- 调用 releaseFileStream 处理文件下载
- 下载完成后执行回调函数(如果有)
6. 释放文件流 - releaseFileStream
处理文件流并触发文件下载。
函数签名
typescript
function releaseFileStream(res: any, fileName: string): Promise<void>参数
res(any): 文件流数据fileName(string): 保存的文件名
使用示例
javascript
import { releaseFileStream } from '@pt/utils/modules/file';
// 在获取到文件流后调用
fetch('https://api.example.com/download/report')
.then(response => response.blob())
.then(blob => {
releaseFileStream(blob, '报告.pdf');
});工作原理
- 将数据转换为 Blob 对象
- 为 IE 浏览器和现代浏览器提供不同的处理方式
- 对于现代浏览器,创建一个临时的
<a>元素 - 设置下载链接和文件名
- 触发下载并清理临时元素和 blob URL
7. 从 URL 获取文件名 - getNameByUrl
从 URL 中提取文件名部分。
函数签名
typescript
function getNameByUrl(url: string): string参数
url(string): 文件 URL
返回值
- 从 URL 中提取的文件名
使用示例
javascript
import { getNameByUrl } from '@pt/utils/modules/file';
const fileName = getNameByUrl('https://example.com/documents/report.pdf');
console.log(fileName); // 输出: "report.pdf"8. 解析文件名(不含扩展名)- parseFileName
从完整文件名中提取不带扩展名的部分。
函数签名
typescript
function parseFileName(fullFileName?: string): string参数
fullFileName(string, 可选): 完整文件名
返回值
- 不含扩展名的文件名,如果无法解析则返回原文件名
使用示例
javascript
import { parseFileName } from '@pt/utils/modules/file';
const name = parseFileName('document.pdf');
console.log(name); // 输出: "document"
// 处理没有扩展名的情况
const namePlain = parseFileName('README');
console.log(namePlain); // 输出: "README"使用注意事项
- 这些函数依赖于浏览器 API,仅适用于客户端环境
- 在服务器端渲染(SSR)环境中,应确保这些函数仅在客户端执行
- 对于大型文件,下载函数可能会消耗较多内存,应谨慎使用
- 带有认证的下载函数依赖于本地存储中的 token,确保用户已登录
- 处理中文文件名时,大多数现代浏览器都能正确处理,无需额外编码
实际应用场景
- 在线代码编辑器中导出用户编写的代码
- 生成和下载动态报告或文档
- 将 API 返回的数据保存为本地文件
- 从受保护的 API 中下载需要认证的文件
- 处理文件名和扩展名以进行文件类型验证
兼容性
这些函数兼容所有现代浏览器,并包含针对 IE 浏览器的特殊处理。它们使用了如下特性:
- Blob API
- URL.createObjectURL
- XMLHttpRequest 的 responseType 支持
- download 属性
- Promise(对于异步操作)