vue 页面导出为pdf与word
vue 页面导出为pdf与word
一.导出为word
基于 docxtemplater 来导出word文档的方法
1.安装引用依赖
// 安装 docxtemplater npm install docxtemplater pizzip --save // 安装 jszip-utils npm install jszip-utils --save // 安装 jszip npm install jszip --save // 安装 FileSaver npm install file-saver --save
2.创建word模板(按自己所需最后导出的样式),放到该vue项目public文件夹下,word文档模板具体的写法可以参考 docxtemplater demo 上的例子
数据定义使用
- js中定义变量:
{value:'测试'}
- word模板中使用语法:
{value}
图片定义使用
- js中定义变量:
{img:'文件路径'}
- word模板中使用语法:
{%img}
3.导出word文档实现:
js引入:
import docxtemplater from 'docxtemplater' import JSZipUtils from 'jszip-utils' import { saveAs } from 'file-saver' import PizZip from 'pizzip'
// 导出word async exportWord() { //这里要引入处理图片的插件,下载docxtemplater后,引入的就在其中了 var ImageModule = require('docxtemplater-image-module-free') var self = this //这里是我的Word路径 JSZipUtils.getBinaryContent('word.docx', function (error, content) { if (error) { throw error } let opts = {} opts.centered = true opts.fileType = 'docx' opts.getImage = (tag) => { return self.base64DataURLToArrayBuffer(tag) } opts.getSize = () => { return [550, 200] //输出的图片宽和高 } let zip = new PizZip(content) let doc = new docxtemplater() doc.attachModule(new ImageModule(opts)) doc.loadZip(zip) doc.setData({ ...self.data, //我的最外层包裹一切要导出的数据名称 }) try { doc.render() } catch (error) { var e = { message: error.message, name: error.name, stack: error.stack, properties: error.properties, } console.log( JSON.stringify({ error: e, }) ) throw error } var out = doc.getZip().generate({ type: 'blob', mimeType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', }) saveAs(out, '导出文件的名称.docx') }) },
导出后的文件与模板一致,如下图所示,导出后可自行修改内容。
二.导出为pdf
原理:使用html2canvas将DOM生成canvas,然后生成对应的图片,将图片生成pdf
注意:页面pdf导出有时候会因为屏幕分辨率出现内容分割问题,只需要固定宽即可!
1.安装引入依赖
npm i html2canvas
npm i jspdf
2.在utils文件夹下新建exportPdf.js文件
文件内容如下:
// 导出页面为PDF格式
import html2Canvas from 'html2canvas'
import JsPDF from 'jspdf'
export function getPdf(title, id) {
html2Canvas(document.querySelector(`#${id}`), {
allowTaint: true
}).then(function (canvas) {
let contentWidth = canvas.width
let contentHeight = canvas.height
let pageHeight = contentWidth / 592.28 * 841.89
let leftHeight = contentHeight
let position = 0
let imgWidth = 595.28
let imgHeight = 592.28 / contentWidth * contentHeight
let pageData = canvas.toDataURL('image/jpeg', 1.0)
let PDF = new JsPDF('', 'pt', 'a4')
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(title + '.pdf')
})
}
3.使用(在需要的页面导入exportPdf.js文件)
<!-- id="pdfHtml"内所有内容就是PDF导出的内容 --> <el-button type="primary" size="mini" @click="exportPDF">导出pdf文件</el-button> <div id="pdfHtml"> 测试导出pdf内容 </div>
import html2Canvas from 'html2canvas'
import { getPdf } from '@/utils/exportPdf.js'
// 导出PDF exportPDF() { getPdf('导出文件的名称', 'pdfHtml')//pdfHtml为导出内容的ID
},
页面展示效果:
导出为pdf后效果:
最好多测试几遍,有时候情况特殊的会出现内容被分割的问题。
注意:导出包含图片的word时,图片类型需要为base64
base64DataURLToArrayBuffer(dataUrl) { const base64String = dataUrl.split(',')[1]; // 提取 base64 编码部分 const binaryString = window.atob(base64String); // 解码 base64 const len = binaryString.length; const bytes = new Uint8Array(len); for (let i = 0; i < len; i++) { bytes[i] = binaryString.charCodeAt(i); } return bytes.buffer; // 返回 ArrayBuffer }