有个需求,要求用户能够选中文本,然后能够将这些选中的文本配置成表格,并导出PDF或图片,要求表格的内容、样式可以根据预设选择自己喜欢的模板,一下是我的实现思路:
通过Wxml-to-canvas+pdfjs实现
1.安装
npm install --save wxml-to-canvas
2.声明组件
{
"usingComponents": {
"wxml-to-canvas": "wxml-to-canvas",
}
}
3. 使用
<video class="video" src="{{src}}">
<wxml-to-canvas class="widget"></wxml-to-canvas>
</video>
<image src="{{src}}" style="width: {{width}}px; height: {{height}}px"></image>
4.获取js实例
const {wxml, style} = require('./demo.js')
Page({
data: {
src: ''
},
onLoad() {
this.widget = this.selectComponent('.widget')
},
renderToCanvas() {
const p1 = this.widget.renderToCanvas({ wxml, style })
p1.then((res) => {
this.container = res
this.extraImage()
})
},
extraImage() {
const p2 = this.widget.canvasToTempFilePath()
p2.then(res => {
this.setData({
src: res.tempFilePath,
width: this.container.layoutBox.width,
height: this.container.layoutBox.height
})
})
}
})
一开始我使用这种方式导出的图片,发现表格还是会有点失真,文字会有偏移效果,并且后续还需要对表格进行样式预设,单个表格在不显示音标的情况下无法自动居中,用这种方式非常麻烦,因此我最终抛弃了这种方式,使用takesnapshot+pdfjs方式实现。
通过takeSnapshot+pdfjs实现
组件介绍:Snapshot.takeSnapshot(Object object) | 微信开放文档
需要在json文件中声明snapshot组件并使用组件包裹住需要转成图片的部分
<snapshot id="view{{index}}" class="intro">
//此处填写
</snapshot>
1.实现样式预设
<snapshot id="view{{index}}" class="intro">
<componetOne wx:if=“{{}}” />
<componetTwo wx:elif=“{{}}” />
<componetThree wx:else />
</snapshot>
只需要将预设的模板在组件中包裹,通过wxif动态选择当前需要渲染的模板样式
注意:因为skyline渲染原因,最好先在skyline模式下写模板样式,要不然转成skyline样式会出错!同时注意skyline渲染有一部分布局样式与css样式是不支持的,具体参考微信官方文档
1.导出图片orPDF
for (let index = 0; index < pageNumber; index++) {
this.createSelectorQuery().select("#view"+index)
.node().exec(res => {
const node = res[0].node
node.takeSnapshot({
// type: 'file' 且 format: 'png' 时,可直接导出成临时文件
type:'arraybuffer',
format: 'png',
success: (res) => {
let f = `${wx.env.USER_DATA_PATH}/hello${index}.png`
const fs = wx.getFileSystemManager();
fs.writeFile({
filePath: f,
data: res.data,
encoding: 'binary',
success(res) {
console.log(res);
wx.compressImage({
src: f,
quality:1,
success(res){
f = res.tempFilePath
src.push(f)
if (src.length >= pageNumber) {
that.setData({
src:src,
})
if (type == 0) {
that.onIdentify()
}else{
that.onImportImg()
}
}
},
complete(res){
console.log(f);
console.log("complete",res);
}
})
},
fail(err) {
console.error('文件写入失败', err);
}
});
},
fail(res) {
console.log("takeSnapshot fail:", res)
},
complete(res){
console.log(77777);
},
})
})
}
这种方式只有在开启skyline渲染模式并要求微信基础库>3.0.0才能够使用,要是版本低会报错,但其实,微信95%以上的用户版本都在3.0.0以上,只有少部分的用户是连微信都不更新的钉子户
3.导出PDF
onIdentify() {
var that = this;
const imagePath = [...this.data.src]
//pdf处理函数
pdfFn(imagePath).then((resl) => {
let fs = wx.getFileSystemManager();
// 写入文件
fs.writeFile({
filePath: wx.env.USER_DATA_PATH + "/" + 'name.pdf',
data: resl.docBase64,
encoding: "base64",
success: resx => {
wx.openDocument({
filePath: wx.env.USER_DATA_PATH + "/" + 'name.pdf',
showMenu: true,
success: function (resxl) {
console.log(resxl);
},
fail(err) {
console.log(err);
}
})
}
})
})
},
3.导出图片
只需要将临时图片文件使用wx.previewImage打开预览即可,用户可自行选择保存
4.pdfjs 图片转换pdf函数
【微信小程序开发】多图片转pdf(可带水印)_微信小程序怎么把图片转换成pdf格式-优快云博客
注意:目前takeSnapshot只支持真机调试,使用微信开发工具预览图片是全黑的