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
}

 

posted @ 2023-09-11 12:09  骄傲一点才可爱  阅读(4885)  评论(6编辑  收藏  举报