Skip to content

文件操作工具

概述

这个模块提供了一组用于文件操作的实用工具函数,包括文件下载、内容导出为文件以及文件扩展名解析等功能。这些函数在前端应用中特别有用,可以帮助您处理文件相关的操作。

函数列表

1. 文件下载函数 - downloadFile

通过 XMLHttpRequest 请求下载文件并使用自定义文件名保存。

函数签名

typescript
function downloadFile(fileInfo: { url: string; name: string }): void

参数

  • fileInfo: 包含以下属性的对象:
    • url (string): 要下载的文件的URL
    • name (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),否则有些浏览器保存时可能变成无扩展名

工作原理

  1. 使用 XMLHttpRequest 发起 GET 请求获取文件内容
  2. 以 blob 形式接收响应数据
  3. 创建一个临时的 <a> 元素并设置其 href 为 blob URL
  4. 设置 download 属性为指定的文件名
  5. 自动触发点击事件下载文件
  6. 清理创建的 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.htmltext/html
svg.svgimage/svg+xml
vue.vuetext/x-template
react.jsxtext/jsx
javascript.jsapplication/javascript
js.jsapplication/javascript
python.pytext/x-python
py.pytext/x-python
typescript.tsapplication/typescript
ts.tsapplication/typescript
css.csstext/css
scss.scsstext/x-scss
sass.sasstext/x-sass
json.jsonapplication/json
markdown.mdtext/markdown
cpp.cpptext/x-c++src
c.ctext/x-csrc
java.javatext/x-java-source
swift.swiftapplication/swift
kotlin.kttext/x-kotlin
rust.rstext/x-rustsrc
mermaid.mermaidtext/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 文件

工作原理

  1. 根据提供的类型确定适当的文件扩展名和 MIME 类型
  2. 生成包含随机 UUID 的文件名(如果未提供文件名)
  3. 使用内容创建一个 Blob 对象
  4. 创建一个临时的 <a> 元素,设置其 href 为 blob URL
  5. 添加元素到 DOM,触发点击下载,然后移除元素
  6. 释放创建的 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); // 输出: "" (空字符串)

工作原理

  1. 使用正则表达式匹配文件名或 URL 中的扩展名部分
  2. 正则表达式能够处理带有查询参数或片段标识符的 URL
  3. 将找到的扩展名转换为小写并返回

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): 文件的 URL
  • fileName (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('下载完成');
});

工作原理

  1. 创建 XMLHttpRequest 请求,设置响应类型为 blob
  2. 从本地存储读取认证 token 并添加到请求头
  3. 发送请求获取文件
  4. 从响应头中解析文件名,或使用提供的文件名,或从 URL 中提取
  5. 调用 releaseFileStream 处理文件下载
  6. 下载完成后执行回调函数(如果有)

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');
  });

工作原理

  1. 将数据转换为 Blob 对象
  2. 为 IE 浏览器和现代浏览器提供不同的处理方式
  3. 对于现代浏览器,创建一个临时的 <a> 元素
  4. 设置下载链接和文件名
  5. 触发下载并清理临时元素和 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"

使用注意事项

  1. 这些函数依赖于浏览器 API,仅适用于客户端环境
  2. 在服务器端渲染(SSR)环境中,应确保这些函数仅在客户端执行
  3. 对于大型文件,下载函数可能会消耗较多内存,应谨慎使用
  4. 带有认证的下载函数依赖于本地存储中的 token,确保用户已登录
  5. 处理中文文件名时,大多数现代浏览器都能正确处理,无需额外编码

实际应用场景

  • 在线代码编辑器中导出用户编写的代码
  • 生成和下载动态报告或文档
  • 将 API 返回的数据保存为本地文件
  • 从受保护的 API 中下载需要认证的文件
  • 处理文件名和扩展名以进行文件类型验证

兼容性

这些函数兼容所有现代浏览器,并包含针对 IE 浏览器的特殊处理。它们使用了如下特性:

  • Blob API
  • URL.createObjectURL
  • XMLHttpRequest 的 responseType 支持
  • download 属性
  • Promise(对于异步操作)

Released under the MIT License.