#在网上找了好多画布污染的办法 都不太行 今天下午竟然稀里糊涂的弄出来了😂 大家慢慢看
先使用 html2canvas 将页面转换成图片(html2canvas 使用方法),然后再将图片导成 pdf
安装 html2canvas
npm i html2canvas
import html2canvas from “html2canvas”;
安装jspdf
npm i jspdf
import JsPDF from ‘jspdf’
页面简单布局 示例:这里是图片列表
<div ref="pdfForm" style="margin-top: 20px">
<FormItem label="申请附件:" v-if="helpApplyModel.tempFileList">
<div style="float: left;margin-right: 10px" v-for="(item,index) in helpApplyModel.tempFileList"
:key="index">
<el-image ref="img{{index}}"
style="width: 100px; height: 100px"
:src="item.url+'?'+new Date().getTime()"
:preview-src-list="getPreview(item.url)">
</el-image>
<p style="text-align: center">{{ item.typeValue }}</p>
</div>
</FormItem>
</div>
下载pdf
pdfDownload: function () {
let myBox = this.$refs.pdfForm; //获取ref里面的内容
html2canvas(myBox, {
useCORS: true, //是否尝试使用CORS从服务器加载图像
allowTaint: false,//是否允许画布污染
dpi: 300, //解决生产图片模糊
scale: 3, //清晰度--放大倍数
}).then(function (canvas) {
let contentWidth = canvas.width
let contentHeight = canvas.height
let pageHeight = contentWidth / 592.28 * 841.89 // 一页pdf显示html页面生成的canvas高度;
let leftHeight = contentHeight //未生成pdf的html页面高度
let position = 0 //pdf页面偏移
//a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高
// let imgWidth = 595.28
let imgWidth = 560.28 //宽度
let imgHeight = 592.28 / contentWidth * contentHeight
let pageData = canvas.toDataURL('image/jpeg', 1.0)//图片转换base64
let PDF = new JsPDF('p', 'pt', 'a4')
// 有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)
//当内容未超过pdf一页显示的范围,无需分页
if (leftHeight < pageHeight) {
PDF.addImage(pageData, 'JPEG', 20, 20, imgWidth, imgHeight)
} else {
while (leftHeight > 0) {
PDF.addImage(pageData, 'JPEG', 20, position, imgWidth, imgHeight)
leftHeight -= pageHeight
position -= 841.89
if (leftHeight > 0) {
PDF.addPage()
}
}
}
PDF.save('下载标题')//下载标题
});
}
但是这样导出的话会有跨域问题 由于是动态图片
会产生跨域问题
解决
- 服务端指定 允许跨域请求的来源
String endPoint = "";
String ak = "";
String sk = "";
// 创建ObsClient实例
ObsClient obsClient = new ObsClient(ak, sk, endPoint);
BucketCors cors = new BucketCors();
List<BucketCorsRule> rules = new ArrayList<BucketCorsRule>();
BucketCorsRule rule = new BucketCorsRule();
ArrayList<String> allowedOrigin = new ArrayList<String>();
// 指定允许跨域请求的来源
allowedOrigin.add("*");
rule.setAllowedOrigin(allowedOrigin);
ArrayList<String> allowedMethod = new ArrayList<String>();
// 指定允许的跨域请求方法(GET/PUT/DELETE/POST/HEAD)
allowedMethod.add("GET");
allowedMethod.add("HEAD");
allowedMethod.add("PUT");
rule.setAllowedMethod(allowedMethod);
ArrayList<String> allowedHeader = new ArrayList<String>();
// 控制在OPTIONS预取指令中Access-Control-Request-Headers头中指定的header是否被允许使用
allowedHeader.add("*");
rule.setAllowedHeader(allowedHeader);
ArrayList<String> exposeHeader = new ArrayList<String>();
// 指定允许用户从应用程序中访问的header
exposeHeader.add("x-obs-expose-header");
rule.setExposeHeader(exposeHeader);
// 指定浏览器对特定资源的预取(OPTIONS)请求返回结果的缓存时间,单位为秒
rule.setMaxAgeSecond(10);
rules.add(rule);
cors.setRules(rules);
obsClient.setBucketCors(CommonConstants.BUCKET_NAME, cors);
- 标签加 crossOrigin = “Anonymous” 或者 crossOrigin = “” 效果一样
这是因为存储在浏览器的图片缓存 和 canvas画布请求图片的域不同
还有一种问题
画布污染导致 canvas.toDataURL 会禁止调用
解决办法
allowTaint: true,//是否允许画布污染 改为false或者不添加 默认就为false