一、vue导出word文档 , 图片加文字
前言: 用一般的方法导出图片是图片链接,而不是直接是一张图片,看来网上很多 vue 都是导出 word 文档文章, 基本很少看到 如何导出word文档图片帯文字,看到几篇也就是把代码一贴,晦涩难懂,经阅读 docxtemplater 官方文档 ,得出以下方法,详细有效
- 先下载相应的依赖包
-- 安装 docxtemplater
npm install docxtemplater pizzip --save
-- 安装 jszip-utils
npm install jszip-utils --save
-- 安装 jszip
npm install jszip --save
-- 安装 FileSaver
npm install file-saver --save
-- 安装 docxtemplater-image-module-free
npm install docxtemplater-image-module-free --save
-
在 public 文件夹下创建 docxs 文件夹并创建 名为
demo.docx
的 word 模板 , 格式如下:(格式错误将无法导出,打印台后打印 error multi)
-
在 src 文件夹中的 util 文件夹(没有这个文件夹自己建)中新建一个
exportWordAndPic.js
文件,代码如下
import docxtemplater from 'docxtemplater'
import PizZip from 'pizzip'
import JSZipUtils from 'jszip-utils'
import { saveAs } from 'file-saver'
import ImageModule from 'docxtemplater-image-module-free'
export default {
methods: {
// 点击导出word
exportWordAndPic (
data,
name,
docTitle = '考场' + data[0].sRoomNo + (name === 'demo2' ? '小纸条' : '签到表')
) {
// 读取并获得模板文件的二进制内容
JSZipUtils.getBinaryContent('/docxs/' + name + '.docx', function (
error,
content
) {
// model.docx是模板。我们在导出的时候,会根据此模板来导出对应的数据
// 抛出异常
if (error) {
throw error
}
var opts = {}
opts.centered = false
opts.getImage = function (tagValue, tagName) {
return new Promise(function (resolve, reject) {
JSZipUtils.getBinaryContent(tagValue, function (error, content) {
if (error) {
return reject(error)
}
return resolve(content)
})
})
}
opts.getSize = function (img, tagValue, tagName) {
if (name === 'demo2') {
return [80, 90]// 图片大小 (这个可以写成动态的,开发文档上有)
} else {
return [45, 50]
}
}
var imageModule = new ImageModule(opts)
// 创建一个PizZip实例,内容为模板的内容
const zip = new PizZip(content)
// 创建并加载docxtemplater实例对象
// eslint-disable-next-line new-cap
const doc = new docxtemplater().loadZip(zip).attachModule(imageModule).compile()
doc.resolveData({ data }).then(function () {
doc.render()
var out = doc.getZip().generate({
type: 'blob',
mimeType: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
})
// 输出文档
saveAs(out, `${docTitle}.doc`)
})
})
}
}
}
- 需要使用到导出word功能的组件代码如下:
- 组件中方法的调用:
- 效果展示:
exportWordAndPic.js
代码分析:
(截图中有一处解释有误, 第16行,出现的报错是·: Can‘t find end of central directory:is this a zip file?
)
二、解决 elementui table 每次重新获取数据时,默认展开下拉框
具体问题如图:
解决办法:
- elementui table组件 给了两个非常有用的属性,合理利用可实现所需要的功能:
- 给 下图标签中加入相应的属性与方法 (缺一不可)
:row-key="getRowKeys"
@expand-change="expandChange"
:expand-row-keys="expands"
4. data 域:
// 列表展开参数
expands: [],
- methods 域中写相应的方法: (仔细想想,其实挺简单的)
// 人性化处理 table 展开行默认展开行
getRowKeys (row) {
return row.erid // id值,看自己row里面有什么id值(当前row里面是 erid),要是唯一的
},
expandChange (row) {
// console.log(row.cid, this.expands[0])
if (row.erid === this.expands[0]) { // 判断是不是本身,如果点击的还是本身,则关闭,人性化
this.expands = []
} else {
if (row.studentList) {
this.expands = [] // 每次点击一个框,出自己以外其他的都不展示, 如果需要方便两个专业考试的对比那就删除本行
if (row) {
this.expands.push(row.erid)// 每次push进去的是每行的ID
}
} else {
this.expands = []// 默认不展开
}
}
},