Vue3 实现导出 Word、Excel、PDF
Vue3 实现导出 Word、Excel、PDF
·
Vue3 实现导出 Word、Excel、PDF
前言
- 本文所提及的导出方法是基于本人自己使用的项目,若要满足自己的项目需求,需要对方法做适量的调整
- 本文知识学习于网上,经过整理所得,时间跨度较长,已遗忘参考于哪个博主,如有侵权,联系即删!
一、导出 Excel
1、按装依赖
npm install -S xlsx
2、方法
- 使用方式参考下文使用示例
import * as XLSX from 'xlsx';
/**
* 导出 Excel 表格
* @param {*} title 表头信息
* @param {*} data 表格体内容
* @param {*} outFileName 保存的文件名
* @param {*} orderProp 序号列的字段名
*/
exportExcel(title, data, outFileName, orderProp) {
let prop = 'prop'
let titleList = this.toolTitleList(title)
let tableData = [
[...titleList]//导出表头
] // 表格表头
data.forEach((tableItem, tableIndex) => {
let rowData = []
title.forEach((titleItem) => {
if (titleItem[prop] === orderProp) {
rowData.push(tableIndex + 1)
} else {
rowData.push(tableItem[titleItem[prop]])
}
})
tableData.push(rowData)
})
// 以下部分才是生成 Excel 的重点
let aoaToSheet = XLSX.utils.aoa_to_sheet(tableData)
let bookNew = XLSX.utils.book_new()
XLSX.utils.book_append_sheet(bookNew, aoaToSheet, outFileName) // 工作簿名称
XLSX.writeFile(bookNew, outFileName + '.xlsx') // 保存的文件名
},
/**
* 获取表头信息
* @param {*} data 传入的表头信息数组
* @returns
*/
toolTitleList(data) {
let result = []
data.forEach(item => {
result.push(item['label'])
})
return result
},
3、在本文中的使用示例
- 在 Vue 中 methods 中使用
- 由于后端返回的数据没有“序号”对应的字段,前端又需要展示,于是最后一个参数用于判断是否有“序号”字段,不需要可以将该参数置为空字符串
methods: {
handleDownloadClick() {
let titleList = [
{
label: "序号",
prop: "order_id",
width: "4%",
},
{
label: "区域名称",
prop: "area_name",
width: "9%",
},
{
label: "厂站名称",
prop: "st_name",
width: "20%",
},
]
let tableList = [
{
area_name: "AREANAME",
st_name: "STNAME"
},
]
let outfilename = "数据表"; // 导出的文件名称
let orderProp = "order_id"; // 序号列对应的字段名称
exportWordExcelPdf.exportExcel(
titleList,
tableList,
outfilename,
orderProp
);
},
}
二、导出 Word
1、按装依赖
npm install -S docxtemplater file-saver jszip-utils pizzip
2、方法
import docxtemplater from 'docxtemplater';
import { saveAs } from 'file-saver';
import JSZipUtils from 'jszip-utils';
import PizZip from 'pizzip';
/**
* 导出 Word 文档
* @param {Object} tempDocxPath 模板文件路径
* @param {Object} wordData 导出数据
* @param {Object} fileName 导出文件名
**/
exportWord(tempDocxPath, wordData, fileName) {
// 读取并获得模板文件的二进制内容
JSZipUtils.getBinaryContent(tempDocxPath, function (error, content) {
if (error) {
throw error;
}
// 创建一个PizZip实例,内容为模板的内容
let zip = new PizZip(content);
// 创建并加载docxtemplater实例对象
let doc = new docxtemplater();
// doc.attachModule(new ImageModule(opts));
doc.loadZip(zip);
doc.setData(wordData);
try {
// 用模板变量的值替换所有模板变量
doc.render();
} catch (error) {
// 抛出异常
let e = {
message: error.message,
name: error.name,
stack: error.stack,
properties: error.properties
};
console.log(JSON.stringify({
error: e
}));
throw error;
}
// 生成一个代表docxtemplater对象的zip文件(不是一个真实的文件,而是在内存中的表示)
let out = doc.getZip().generate({
type: "blob",
mimeType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
});
// 将目标文件对象保存为目标类型的文件,并命名
saveAs(out, fileName + ".docx");
});
},
3、在本文中的使用示例
- 第一个参数是模版文件的路径,在 Vue3 项目中放在 public 目录下
- 第二个参数是在模版中展示的数据内容,默认是一个对象的形式,模版中使用示例如下图
- 第三个参数是导出的文件名
methods: {
exportWordFile() {
let param = {
message: "这是一段文本信息"
}
exportWord("/word.docx", param, "exportTestWord");
},
},
三、导出 PDF
1、安装依赖
npm install -S html2canvas jspdf
2、方法
import html2Canvas from 'html2canvas'
import JsPDF from 'jspdf'
/**
* 导出 PDF 文件
* @param {*} dom 要导出的 PDF 元素
* @param {*} outFileName 导出的文件名
*/
exportPdf(dom, outFileName) {
var element = document.querySelector(dom); // 这个dom元素是要导出pdf的div容器
// element.style.height = param.height
setTimeout(() => {
html2Canvas(element).then(function (canvas) {
var contentWidth = canvas.width;
var contentHeight = canvas.height;
// 一页pdf显示html页面生成的canvas高度;
var pageHeight = contentWidth / 592.28 * 841.89;
// 未生成pdf的html页面高度
var leftHeight = contentHeight;
// 页面偏移
var position = 0;
// a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高
var imgWidth = 595.28;
var imgHeight = 592.28 / contentWidth * contentHeight;
var pageData = canvas.toDataURL('image/jpeg', 1.0);
var pdf = new JsPDF('', 'pt', 'a4');
// 有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)
// 当内容未超过pdf一页显示的范围,无需分页
if (leftHeight < pageHeight) {
pdf.addImage(pageData, 'JPEG', 0, 0, imgWidth, imgHeight);
} else {
while (leftHeight > 0) {
pdf.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight)
leftHeight -= pageHeight;
position -= 841.89;
// 避免添加空白页
if (leftHeight > 0) {
pdf.addPage();
}
}
}
pdf.save(outFileName + '.pdf');
});
// element.style.height = param.minHeight
}, 0);
}
3、在本文中的使用示例
methods: {
/**
* 下载为PDF
*/
handleDownloadPdfClick() {
// console.log("下载为PDF=>");
let dom = "#pdfDom"
let outFileName = "Pdf导出"
this.getPdf(dom, outFileName);
},
},
四、综合文件
1、安装依赖
npm install -S xlsx
npm install -S docxtemplater file-saver jszip-utils pizzip
npm install -S html2canvas jspdf
2、工具文件
- exportWordExcelPdf.js
import docxtemplater from 'docxtemplater';
import { saveAs } from 'file-saver';
import html2Canvas from 'html2canvas';
import JsPDF from 'jspdf';
import JSZipUtils from 'jszip-utils';
import PizZip from 'pizzip';
export default {
/**
* 导出 Excel 表格
* @param {*} title 表头信息
* @param {*} data 表格体内容
* @param {*} outFileName 保存的文件名
* @param {*} orderProp 序号列的字段名
*/
exportExcel(title, data, outFileName, orderProp) {
let prop = 'prop'
let titleList = this.toolTitleList(title)
let tableData = [
[...titleList]//导出表头
] // 表格表头
data.forEach((tableItem, tableIndex) => {
let rowData = []
title.forEach((titleItem) => {
if (titleItem[prop] === orderProp) {
rowData.push(tableIndex + 1)
} else {
rowData.push(tableItem[titleItem[prop]])
}
})
tableData.push(rowData)
})
// 以下部分才是生成 Excel 的重点
let aoaToSheet = XLSX.utils.aoa_to_sheet(tableData)
let bookNew = XLSX.utils.book_new()
XLSX.utils.book_append_sheet(bookNew, aoaToSheet, outFileName) // 工作簿名称
XLSX.writeFile(bookNew, outFileName + '.xlsx') // 保存的文件名
},
/**
* 获取表头信息
* @param {*} data 传入的表头信息数组
* @returns
*/
toolTitleList(data) {
let result = []
data.forEach(item => {
result.push(item['label'])
})
return result
},
/**
* 导出 Word 文档
* @param {Object} tempDocxPath 模板文件路径
* @param {Object} wordData 导出数据
* @param {Object} fileName 导出文件名
**/
exportWord(tempDocxPath, wordData, fileName) {
// 读取并获得模板文件的二进制内容
JSZipUtils.getBinaryContent(tempDocxPath, function (error, content) {
if (error) {
throw error;
}
// 创建一个PizZip实例,内容为模板的内容
let zip = new PizZip(content);
// 创建并加载docxtemplater实例对象
let doc = new docxtemplater();
// doc.attachModule(new ImageModule(opts));
doc.loadZip(zip);
doc.setData(wordData);
try {
// 用模板变量的值替换所有模板变量
doc.render();
} catch (error) {
// 抛出异常
let e = {
message: error.message,
name: error.name,
stack: error.stack,
properties: error.properties
};
console.log(JSON.stringify({
error: e
}));
throw error;
}
// 生成一个代表docxtemplater对象的zip文件(不是一个真实的文件,而是在内存中的表示)
let out = doc.getZip().generate({
type: "blob",
mimeType: "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
});
// 将目标文件对象保存为目标类型的文件,并命名
saveAs(out, fileName);
});
},
/**
* 导出 PDF 文件
* @param {*} dom 要导出的 PDF 元素
* @param {*} outFileName 导出的文件名
*/
exportPdf(dom, outFileName) {
var element = document.querySelector(dom); // 这个dom元素是要导出pdf的div容器
// element.style.height = param.height
setTimeout(() => {
html2Canvas(element).then(function (canvas) {
var contentWidth = canvas.width;
var contentHeight = canvas.height;
// 一页pdf显示html页面生成的canvas高度;
var pageHeight = contentWidth / 592.28 * 841.89;
// 未生成pdf的html页面高度
var leftHeight = contentHeight;
// 页面偏移
var position = 0;
// a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高
var imgWidth = 595.28;
var imgHeight = 592.28 / contentWidth * contentHeight;
var pageData = canvas.toDataURL('image/jpeg', 1.0);
var pdf = new JsPDF('', 'pt', 'a4');
// 有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)
// 当内容未超过pdf一页显示的范围,无需分页
if (leftHeight < pageHeight) {
pdf.addImage(pageData, 'JPEG', 0, 0, imgWidth, imgHeight);
} else {
while (leftHeight > 0) {
pdf.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight)
leftHeight -= pageHeight;
position -= 841.89;
// 避免添加空白页
if (leftHeight > 0) {
pdf.addPage();
}
}
}
pdf.save(outFileName + '.pdf');
});
// element.style.height = param.minHeight
}, 0);
}
}
3、在本文中的使用示例
- 引入
import exportWordExcelPdf from "./../../utils/exportWordExcelPdf";
- 使用
methods: {
handleDownloadClick() {
let outfilename = "厂站数据表";
let orderProp = "order_id"; // 序号列对应的字段名称
exportWordExcelPdf.exportExcel(
this.factoryTableTitle,
this.factoryTableList,
outfilename,
orderProp
);
},
}
总结
更多推荐
已为社区贡献1条内容
所有评论(0)