一、excel文件导出
1、引入npm包

npm install --save table-xlsx @pengchen/xlsx
第三方包文档:https://pengchen96.github.io/table-xlsx/docs/tutorial-basics/start
表格支持行/列合并

2、定义导出函数

/*** export table* @param data 表格数据* @param columns 表格表头* @param fileName 导出文件名*/
export function onTableExport(data, columns, fileName) {// 过滤无用的操作列const tColumns = columns.filter(item => item.dataIndex !== 'action')const thead = [{title: fileName, // 将文件名作为excel表格总标题children: tColumns}]exportFile({columns: thead,dataSource: data,cellStyle: { // 单元格样式alignmentHorizontal: 'center',borderColorRgb: '000000'},headerCellStyle: { // 表头样式fillFgColorRgb: 'ffffff',fontBold: false,borderColorRgb: '000000',alignmentHorizontal: 'center'},bodyCellStyle: { // 表格内容单元格样式alignmentHorizontal: 'center'},fileName: `${fileName + new Date().getTime()}.xlsx`})
}

4、使用

data() {return {columns: [{title: 'ID',dataIndex: 'id',align: 'center',},{title: '计划名',dataIndex: 'name',align: 'center',},{title: '开始时间',dataIndex: 'createTime',align: 'center',customRender: text => moment(text).format('YYYY-MM-DD HH:MM:SS')},{title: '结束时间',dataIndex: 'endTime',align: 'center',customRender: text => moment(text).format('YYYY-MM-DD HH:MM:SS')},{title: '操作',dataIndex: 'action',align: 'center',fixed: 'right',scopedSlots: { customRender: 'action' }}],dataSource: []}
}
...methods: {planExport() {// this.$toolsFn.是定义全局的工具函数let data = this.$toolsFn.deepCopy(this.dataSource) // 深拷贝数据再进行处理data.map(item => {// 转换时间格式 - 如2022-09-07 22:09:03item.createTime = moment(item.createTime).format('YYYY-MM-DD HH:MM:SS')item.endTime = moment(item.endTime).format('YYYY-MM-DD HH:MM:SS')})this.$toolsFn.onTableExport(data, this.columns, '生产计划表')},}

二、pdf文件导出

通过html2canvas对已经写好的页面生成图片,再通过jspdf把生成好的图片封装成pdf文件(不可编辑)

2、定义导出pdf函数

import html2Canvas from 'html2canvas'
import JsPDF from 'jspdf'
import $ from 'jquery'
export default {install(Vue, options) {Vue.prototype.getPdf = function(node, title) {const A4_WIDTH = 592.28const A4_HEIGHT = 841.89document.documentElement.scrollTop = 0 // 恢复滚动条const imageWrapper = document.querySelector('#' + node) // 获取DOMlet pageHeight = (imageWrapper.scrollWidth / A4_WIDTH) * A4_HEIGHTlet pItem = imageWrapper.querySelectorAll('.pdf')// 判断当前dom节点是不是处于A4页面底部const isSplit = (nodes, index, pageHeight) => {if (nodes[index].offsetTop + nodes[index].offsetHeight < pageHeight &&nodes[index + 1] &&nodes[index + 1].offsetTop + nodes[index + 1].offsetHeight > pageHeight) {return true}return false}// 解决分页字体分割问题for (let i = 0; i < pItem.length; i++) {let multiple = Math.ceil((pItem[i].offsetTop + pItem[i].offsetHeight) / pageHeight)if (isSplit(pItem, i, multiple * pageHeight)) {let divParent = pItem[i].parentNode // 获取该div的父节点let newNode = document.createElement('div')newNode.className = 'emptyDiv'newNode.style.background = '#ffffff'let _H = multiple * pageHeight - (pItem[i].offsetTop + pItem[i].offsetHeight)//留白newNode.style.height = _H + 180 + 'px'newNode.style.width = '100%'let next = pItem[i].nextSibling // 获取div的下一个兄弟节点// 判断兄弟节点是否存在if (next) {// 存在则将新节点插入到div的下一个兄弟节点之前,即div之后divParent.insertBefore(newNode, next)} else {// 不存在则直接添加到最后,appendChild默认添加到divParent的最后divParent.appendChild(newNode)}}}html2Canvas(imageWrapper, {allowTaint: true, // 开启跨域scale: 4, // 设置清晰度,数值越高越清晰,生成的图片越大useCORS: true,backgroundColor: '#FFF'// dpi: 350}).then(function(canvas) {let contentWidth = canvas.widthlet contentHeight = canvas.height//一页pdf显示html页面生成的canvas高度;let pageHeight = (contentWidth / A4_WIDTH) * A4_HEIGHT//生成pdf的html页面高度let htmlHeight = contentHeight//页面偏移let position = 0//a4纸的尺寸[A4_WIDTH,A4_HEIGHT],html页面生成的canvas在pdf中图片的宽高let imgWidth = A4_WIDTHlet imgHeight = (A4_WIDTH / contentWidth) * contentHeightlet pageData = canvas.toDataURL('image/jpeg', 1.0)// 2为上面的scale 缩放了2倍let PDF = new JsPDF('', 'pt', 'a4')//有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)//当内容未超过pdf一页显示的范围,无需分页if (htmlHeight < pageHeight) {PDF.addImage(pageData, 'JPEG', 4, 0, imgWidth, imgHeight)} else {while (htmlHeight > 0) {PDF.addImage(pageData, 'JPEG', 4, position, imgWidth, imgHeight)htmlHeight -= pageHeightposition -= 841.89if (htmlHeight > 0) {//避免添加空白页PDF.addPage()}}}PDF.save(title + '.pdf')// 移除添加的空div - 偷懒用了jquery$('.emptyDiv').remove()})}}
}

3、定义页面纯粹的vue-html页面
4、调用

 exportPdf() {this.contractVisible = falsethis.$nextTick(() => {this.getPdf('pdfDom', '某某合同')})}

三、word文件导出
1、引入npm包

npm install pizzip --save
npm install docxtemplater --svae
npm install jszip-utils --save
npm install file-saver --save

2、 定义exportDocx.js文件
参考如下代码: (我也是参考下面代码)

import PizZip from 'pizzip'
import docxtemplater from 'docxtemplater'
import JSZipUtils from 'jszip-utils'
import { saveAs } from 'file-saver'
/*** 将图片的url路径转为base64路径* 可以用await等待Promise的异步返回* @param {Object} imgUrl 图片路径*/
export const getBase64Sync = imgUrl => {return new Promise(function(resolve, reject) {// 一定要设置为let,不然图片不显示let image = new Image()// 解决跨域问题image.crossOrigin = 'anonymous'//图片地址image.src = imgUrl// image.onload为异步加载image.onload = function() {let canvas = document.createElement('canvas')canvas.width = image.widthcanvas.height = image.heightlet context = canvas.getContext('2d')context.drawImage(image, 0, 0, image.width, image.height)//图片后缀名let ext = image.src.substring(image.src.lastIndexOf('.') + 1).toLowerCase()//图片质量let quality = 0.8//转成base64let dataurl = canvas.toDataURL('image/' + ext, quality)//返回resolve(dataurl)}})
}
/*** 将base64格式的数据转为ArrayBuffer* @param {Object} dataURL base64格式的数据*/
const base64DataURLToArrayBuffer = dataURL => {const base64Regex = /^data:image\/(png|jpg|jpeg|svg|svg\+xml);base64,/if (!base64Regex.test(dataURL)) {return false}const stringBase64 = dataURL.replace(base64Regex, '')let binaryStringif (typeof window !== 'undefined') {binaryString = window.atob(stringBase64)} else {binaryString = new Buffer(stringBase64, 'base64').toString('binary')}const len = binaryString.lengthconst bytes = new Uint8Array(len)for (let i = 0; i < len; i++) {const ascii = binaryString.charCodeAt(i)bytes[i] = ascii}return bytes.buffer
}/*** 导出word,支持图片* @param {Object} docxPath 模板文件路径* @param {Object} wordData 导出数据* @param {Object} fileName 导出文件名* @param {Object} imgSize 自定义图片尺寸*/
export const exportWord = (docxPath, wordData, fileName, imgSize) => {//这里要引入处理图片的插件var ImageModule = require('docxtemplater-image-module-free')const expressions = require('angular-expressions')// 读取并获得模板文件的二进制内容JSZipUtils.getBinaryContent(docxPath, function(error, content) {if (error) {throw error}expressions.filters.size = function(input, width, height) {return {data: input,size: [width, height]}}// 图片处理let opts = {//图像是否居中centered: false}opts.getImage = chartId => {//console.log(chartId);//base64数据//将base64的数据转为ArrayBufferreturn base64DataURLToArrayBuffer(chartId)}opts.getSize = function(img, tagValue, tagName) {//自定义指定图像大小if (imgSize.hasOwnProperty(tagName)) {return imgSize[tagName]} else {return [600, 350]}}// 创建一个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)})
}

3、创建word文件模板
(1)、利用office或wps穿创建一个word文件并保存至vue项目的public文件夹下
在word模板中变量用中括号定义{变量名},表格需要在头尾分别定义{#table}{/table}
例如:

将word文件存入public文件夹中

5、页面调用

methods: {...generateWord() {let data  = {name: '采购',NO: this.sn,signTime: moment(this.signTime).format('YYYY年MM月DD日'),sName: 'xxx公司',sAddress: '深圳市XXXX厂房',sPhone: '0510-85311222',sFaxNo: '0510-85310796',bName: recorData.customName,bDealAddress: recorData.dealAddress,bPhone: recorData.saleCustomer.mobile,bFaxNo: recorData.saleCustomer.fac,table: [...this.dataSurce],...}exportWord('/contract.docx', data, '购销合同')},
...
}

vue-实战记录-前端导出excel文件、pdf文件、word文件相关推荐

  1. vue+elementui表格前端导出excel以及自定义导出样式

    vue+elementui表格前端导出excel以及自定义导出样式 项目遇到前端自己导出表格,我自己把后端给我的数据处理了一波,合并重复列啊,以及表头合并啊.可没想到导出竟然也要前端自己来弄,于是乎请 ...

  2. Vue实现在前端导出Excel

    安装依赖 进入项目文件夹,打开cmd或者在Webstorm中的Terminal中输入: npm install -S file-saver xlsx npm install -D script-loa ...

  3. 【项目实战】批量导出excel,并打包zip文件【连载中】

    一.需求描述 该需求是要在课程模块里的课程任务推送-报表模块,任务推送报表(权限*)导出用户学习总学习记录,若课程任务推送涉及多个课程,则需要生产多个sheet页,每个sheet页的名称按课程名称展示 ...

  4. js vue 设置excel单元格样式_vue项目使用xlsx-style实现前端导出Excel样式修改(添加标题,边框等),并且上传npm踩坑记录...

    前段时间,我们项目提出一个前端导出Excel表格的需求, 这个很简单,利用xlsx,file-saver很容易实现(网上很多教程). 后来需要加入标题,标题居中显示,加入边框等等样式需求,这就给我很多 ...

  5. vue导出excel加一个进度条_Vue实现在前端导出Excel

    安装依赖 进入项目文件夹,打开cmd或者在Webstorm中的Terminal中输入: npm install -S file-saver xlsx npm install -D script-loa ...

  6. php excel模板导出、openoffice excel转pdf、多文件压缩下载

    最近两周都在弄关于excel模板导出.excel转pdf.多文件压缩下载.弄得头都大了,接下来说说实现的方法吧. 我用的是laravel5.1的框架,读取模板生成excel,并且插入图片,直接上代码 ...

  7. 在vue中把数据导出Excel文件

    在vue中把数据导出Excel文件 第一次尝试写文章 在vue中把数据导出成Excel格式的文件,话不多,上代码: 第一步我们要先安装几个集成的插件 npm install -S file-saver ...

  8. vue-json-excel前端导出excel教程

    vue-json-excel是一个专门为解决前端导出Excel而开发的一个组件库. 个人认为,导出在前端做,不是特别合适,最好是后端提供导出下载文件接口,如果后端确实不想提供接口,要让你做前端导出,那 ...

  9. 前端导出excel自定义样式(行高除外)

    前端导出excel需要用到的依赖有xlsx.xlsx-style import XLSX from 'xlsx'; import XLSXStyle from 'xlsx-style'; npm in ...

最新文章

  1. 3.3. shutdown
  2. 17条避坑指南:一份来自谷歌的数据库经验贴
  3. 一个跨国银行的敏捷转型案例要点之全员培训
  4. 【转】云社区 博客 博客详情 二维异形件排版算法介绍(一)
  5. Json学习总结(4)——Json基础知识回顾
  6. cocos2dx学习:TexturePacker的使用
  7. 产业研发用地_金阊新城控制规划调整 新增学校 住宅及产业研发用地
  8. websockets 断开问题解决方案
  9. 安装Adobe Reader 时报错:HRESULT:0x80070422
  10. excel服务器导出文件,excel服务器导出文件夹
  11. DINO:自监督ViT的新特性
  12. pytorch保存模型pth_浅谈pytorch 模型 .pt, .pth, .pkl的区别及模型保存方式
  13. 影视后期制作学习(AE)(时钟动画制作)
  14. vue二级路由和重定向问题
  15. 用jquery制作2048小游戏(超详细)
  16. Linux命令基础入门
  17. 软件评估报告和软件可行性分析文档搜集
  18. 软件开发中的角色分工
  19. GAN论文详细解读+思想
  20. Ubuntu18.04 安装 Idea 2018.2 Ultimate

热门文章

  1. 同学聚会,其本质就是
  2. java性能检测工具_Java自带的性能监测工具之jmap
  3. 新代系统反向间隙参数_新代系统数控机床价格_数控机床6140相关-佛山市顺德锐锋五金机械有限公司...
  4. 三星S5PV210的启动
  5. 详细!如何判断各种电子元器件受损表现
  6. ACPI Specification 第二章 条款的定义
  7. oracle银行勾兑,鸿富兴企业银行对账系统
  8. python决策树及规则解析(真实案例完整流程)
  9. 我们一起学linux之V4L2摄像头应用流程
  10. 计算机专业实验课,教你如何上好计算机课程的实验课