在实际开发中,我们经常会遇到需要让用户上传文档并读取其内容的需求。本文将以 uni-app/微信小程序为例,介绍如何在前端实现读取 txt 和 docx 文件内容,并给出完整的代码实现和注意事项。
依赖安装
npm install jszip fast-xml-parser
核心代码实现
新建 utils/fileReader.js
import JSZip from 'jszip';
import { XMLParser } from 'fast-xml-parser';
/**
* 读取 docx 文件内容
*/
export async function readDocxContent(filePath) {
// 1. 读取为 ArrayBuffer
const arrayBuffer = await new Promise((resolve, reject) => {
uni.getFileSystemManager().readFile({
filePath,
encoding: 'binary',
success: (res) => resolve(res.data),
fail: (err) => reject(new Error('读取文件失败: ' + err.errMsg))
});
});
// 2. 解压
const zip = await JSZip.loadAsync(arrayBuffer);
const documentXml = await zip.file('word/document.xml').async('string');
// 3. 解析 xml
const parser = new XMLParser();
const json = parser.parse(documentXml);
// 4. 提取文本内容
let text = '';
function extractText(node) {
if (typeof node === 'string') {
text += node;
} else if (typeof node === 'object') {
for (const key in node) {
extractText(node[key]);
}
}
}
extractText(json);
return text.replace(/\s+/g, ' ').trim();
}
/**
* 读取 txt 文件内容
*/
export function readTxtContent(filePath) {
return new Promise((resolve, reject) => {
uni.getFileSystemManager().readFile({
filePath,
encoding: 'utf8',
success: (res) => resolve(res.data),
fail: (err) => reject(new Error('读取txt失败: ' + err.errMsg))
});
});
}
调用示例
import { readDocxContent, readTxtContent } from '@/utils/fileReader.js';
methods: {
upload() {
wx.chooseMessageFile({
count: 1,
type: 'file',
extension: ['txt', 'docx'],
success: (res) => {
const file = res.tempFiles[0].path;
const fileName = res.tempFiles[0].name;
const ext = fileName.split('.').pop().toLowerCase();
let contentPromise;
if (fileExt === 'docx') {
contentPromise = readDocxContent(file);
} else if (fileExt === 'txt') {
contentPromise = readTxtContent(file);
} else {
wx.hideLoading();
wx.showToast({
title: '不支持的文件类型',
icon: 'none'
});
return;
}
// 读取文件内容
contentPromise.then(content => {
wx.hideLoading();
console.log('文件内容:', content);
}).catch(error => {
wx.hideLoading();
console.error('读取文件失败:', error);
wx.showToast({
title: error.message,
icon: 'none',
duration: 3000
});
});
}
});
}
}