注释写给有缘人,更多详细内容请参考附录中的参考文档
// 导入XLSX模块,用于生成EXCEL文件
import XLSX from '@/common/xlsx.full.min.js';
// EXCEL导出方法实现
exportExcel() {
// #ifdef APP-PLUS
uni.showModal({
title: '提示',
content: '是否确认导出数据到EXCEL',
success: res => {
if (res.confirm) {
const title = '导出标题';
const wb = XLSX.utils.book_new();
// this.excelData为即将导出数据的JSON格式
const ws = XLSX.utils.json_to_sheet(this.excelData);
const csvws = XLSX.utils.sheet_to_csv(ws);
// --------------------------------------------------
// --------------------------------------------------
// 导出功能从这里开始
// --------------------------------------------------
// --------------------------------------------------
// 操作系统文件,实现导出功能
/**
* plus.io.requestFileSystem(type, succesCB, errorCB) ===> 请求本地文件系统对象
* @param {Number} type (必选) 本地文件系统常量,可取plus.io下的常量,如plus.io.PRIVATE_DOC(Number类型,固定值为2)、plus.io.PUBLIC_DOCUMENTS(Number类型,固定值为3)等
* @param {FileSystemSuccessCallback} succesCB (必选) 请求文件系统成功的回调
* @param {FileSystemSuccessCallback} errorCB (可选) 请求文件系统失败的回调
*/
// fs匹配上述succesCB
// fsErr匹配上述errorCB
plus.io.requestFileSystem(plus.io.PUBLIC_DOCUMENTS, fs => {
// fs.root ===> 根目录操作对象DirectoryEntry
// DirectoryEntry ===> 文件系统中的目录对象,用于管理特定的本地目录
/**
* fs.root.getFile(path, flag, succesCB, errorCB) ===> 创建或打开当前目录(这里使用了fs.root,表示根目录。在Android中“/storage/emulated/0”代表根目录)下指定的文件。 创建或打开文件操作对象成功通过succesCB回调返回,失败则通过errorCB返回
* @param {String} path (必选) 要操作文件相对于当前目录的地址
* @param {Flags} flag (可选) 要操作文件或目录的参数
* @param {FileEntrySuccessCallback} succesCB (可选) 创建或打开文件成功的回调函数
* @param {FileErrorCallback} errorCB (可选) 创建或打开文件失败的回调函数
*/
/**
* {create: false, exclusive: false}匹配上述flag,是Flags的实例
* Flags是JSON对象,获取文件操作的参数
* {Boolean} create 是否创建对象标记,指示,如果文件或目录不存在时,是否进行创建,默认值为false
* {Boolean} exclusive 反向操作标记,其本身没有任何效果,需与create属性值设置为true时一起使用,如果目标文件或目录已经存在则会导致文件或目录打开失败,默认值为false
*
* 总结:这个Flags在这里没有实际作用,只是作为一个占位符,引出下述成功的回调函数fileEntry
*/
// fileEntry匹配上述succesCB
// 此程序没有写失败回调,无法匹配上述errorCB
fs.root.getFile(`${title}.csv`, {create: false}, fileEntry => {
/**
* fileEntry.createWriter(succesCB, errorCB) ===> 获取写文件操作对象成功通过succesCB回调返回,失败则通过errorCB返回
* @param {FileWriterSuccessCallback} succesCB (可选) 获取写文件操作对象成功的回调函数
* @param {FileErrorCallback} errorCB (可选) 获取写文件操作对象失败的回调函数
*/
// writer匹配上述succesCB
// writerErr匹配上述errorCB
fileEntry.createWriter(writer => {
/**
* writer.onwrite(event) ===> 写入文件成功完成的回调函数
* @param {FileEvent} event (必选) 文件事件对象
*/
writer.onwrite = e => {
uni.showModal({
title: '提示',
content: `导出成功,文件路径为${e.target.fileName.replace('/storage/emulated/0', '')}`,
cancelText: '了解并关闭',
confirmText: '预览文件',
success: result => {
if (result.confirm) {
uni.openDocument({
filePath: `file://${e.target.fileName}`,
})
}
}
});
}
/**
* writer.write(data) ===> 向文件中写入数据
* @param {String} data (必选) 要写入的数据内容
*/
writer.write(csvws);
}, writerErr => {
uni.showToast({
title: '导出文件失败,请检查是否有权限',
icon: 'none'
});
})
})
}, fsErr => {
uni.showToast({
title: '导出文件失败,请检查是否有权限',
icon: 'none'
});
})
// --------------------------------------------------
// --------------------------------------------------
// 导出功能到这里结束
// --------------------------------------------------
// --------------------------------------------------
}
},
});
// #endif
// #ifndef APP-PLUS
uni.showToast({
title: '该功能仅支持手机操作',
icon: 'none'
})
// #endif
}
附参考链接:
- CDN => XLSX
- html5+官方文档 => requestFileSystem
- uni-app官方文档
2022-08-03:
补一份xlsx格式的导出
有3个坑:
<meta charset="UTF-8">
这是必须的,不然会乱码,默认ANSI编码- 因为xml的格式比较旧,兼容性较差,office如果不用低版本的话会有警告弹框
- name.xlsx最好改成name.xls,这样即使警告也能强行打开
// 操作系统文件,实现导出功能 => XLSX格式
// 下载的表格模板数据
let jsonData = `<tr><th>AA</th><th>BB</th><th>CC</th></tr>`
for (let i = 0; i < this.previewList.length; i++) {
jsonData += `<tr><td>${this.previewList[i]['XX']}</td><td>${this.previewList[i]['XX']}</td><td style="mso-number-format:'\@';">${this.previewList[i]['XX']}</td></tr>`
}
let template= `<html xmlns:o="urn:schemas-microsoft-com:office:office"
xmlns:x="urn:schemas-microsoft-com:office:excel"
xmlns="http://www.w3.org/TR/REC-html40">
<head><meta charset="UTF-8"><!--[if gte mso 9]><xml encoding="UTF-8"><x:ExcelWorkbook><x:ExcelWorksheets>
<x:ExcelWorksheet><x:Name>报表</x:Name><x:WorksheetOptions><x:DisplayGridlines/>
</x:WorksheetOptions></x:ExcelWorksheet></x:ExcelWorksheets></x:ExcelWorkbook></xml>
<![endif]--></head><body><table>${jsonData}</table></body></html>`
plus.io.requestFileSystem(plus.io.PUBLIC_DOCUMENTS, fs => {
fs.root.getFile(`${title}.xlsx`, {create: true}, fileEntry => {
....