摘要:正常用法引入可查看官方说明根据不同需求,使用中并没有想象中那么容易。问题输入中文时,生成的内容变成乱码解决方法引入和。。安寝移動生行組。
正常用法
引入jspdf.min.js
var doc = new jsPDF()
doc.text("Hello world!", 10, 10)
doc.save("a4.pdf")
api可查看官方说明 jsPDF
根据不同需求,使用中并没有想象中那么容易。
问题1:输入中文时,生成的pdf内容变成乱码
解决方法:
引入jspdf.customfonts.min.js 和 default_vfs.js
var doc = new jsPDF();
doc.addFont("NotoSansCJKjp-Regular.ttf", "NotoSansCJKjp", "normal");
doc.setFont("NotoSansCJKjp");
doc.text(15, 30, "こんにちは。はじめまして。");
//multi-lines Test
var paragraph = "相次いで廃止された寝台列車に代わり、いまや夜間の移動手段として主力になりつつある夜行バス。「安い」「寝ながら移動できる」などのメリットを生かすため、運行ダイヤはどのように組まれているのでしょうか。夜遅く出て、朝早く着くというメリット夜行バスを使うメリットといえば、各種アンケートでもいちばん多い回答の「安い」以外に、";
var lines = doc.splitTextToSize(paragraph, 150);
doc.text(15, 60, lines);
doc.save("custom_fonts.pdf");
参考 jsPDF-CustomFonts-support
问题2:如何给文字添加超链接
解决方法:
pdf.textWithLink("下载", 30, 40, { url: "https://www.google.com/" });
问题3:导出后的pdf黑黑的一片
解决方法:
由于html内容过长,图片较多较长的时候。jsPDF无法导出,可以对页面进行分步截取,然后进行拼接,还可以进行更好的分页
pdf.addPage();
问题4:分步导出后的pdf还是黑黑的一片
解决方法:
导出PDF时,先只显示第一步需要导出的内容,导出完毕后,隐藏导出的页面内容,显示下一步需要导出的页面内容。
以下为部分函数源码,可作为参考
var exporting = false;
var progressLen = $(".cut-box").length;
var resultBoxLength = $(".result-box").length;
$(".export-pdf").click(function(){
if(exporting){
return false;
}
exporting = true;
console.log("export-pdf")
// 保存时先显示所有测试图片,隐藏按钮
var imglen = $("img.lazy").length;
for(var i=0;i" });
pdf.textWithLink("导导导导", 500, 40, { url: "" });
$(".export-pdf").css("display","inline-block");
setProgress(progressIndex);
newHtmlCanvas(pdf,resultBoxIndex,progressIndex);
},
//背景设为白色(默认为黑色)
background: "#fff",
useCORS:true
})
})
//pdf 要输入的pdf,boxLength循环长度,h当前截取的位置
function newHtmlCanvas(pdf,resultBoxIndex,progressIndex){
console.log("resultBoxIndex:"+resultBoxIndex);
console.log($(".result-box:eq("+resultBoxIndex+") .cut-box:eq(0)").offset().top)
var cutBoxLen = $(".result-box:eq("+resultBoxIndex+") .cut-box").length;
var cutBoxIndex = 1;
if(resultBoxIndex!=0){
pdf.addPage();
}
var firstSub = 0;
if(resultBoxIndex==0){
firstSub = 120;
}
html2canvas(
$(".result-box:eq("+resultBoxIndex+")"),
{
dpi: 172,//导出pdf清晰度
height:$(".result-box:eq("+resultBoxIndex+") .cut-box:eq(0)").offset().top+$(".result-box:eq("+resultBoxIndex+") .cut-box:eq(0)").innerHeight()-firstSub,
onrendered: function (canvas) {
var contentWidth = canvas.width;
var contentHeight = canvas.height;
//一页pdf显示html页面生成的canvas高度;
var pageHeight = contentWidth / 592.28 * 841.89;
// if(pageHeight>2000){
// pageHeight = 2000
// }
//未生成pdf的html页面高度
var leftHeight = contentHeight;
//pdf页面偏移
var position = 20;
//html页面生成的canvas在pdf中图片的宽高(a4纸的尺寸[595.28,841.89])
var imgWidth = 555.28;
var imgHeight = 555.28 / contentWidth * contentHeight;
var pageData = canvas.toDataURL("image/jpeg", 1.0);
//有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)
//当内容未超过pdf一页显示的范围,无需分页
if(resultBoxIndex==0){
position=80;
// pageHeight = pageHeight -position;
}
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();
}
}
}
if(cutBoxLen>cutBoxIndex){
console.log("有1个以上的子cut-box");
$(".result-box:eq("+resultBoxIndex+") .cut-box:eq("+(cutBoxIndex-1)+")").css("display","none");
$(".result-box:eq("+resultBoxIndex+") .cut-box:eq("+(cutBoxIndex)+")").css("display","inline-block");
pdf.addPage();
progressIndex++;
setProgress(progressIndex);
connectHtmlCanvas(pdf,resultBoxIndex,cutBoxLen,cutBoxIndex,progressIndex);
}else{
console.log("只有1个子cut-box");
if(resultBoxIndex==resultBoxLength-1){
console.log("当前为最后一个resultbox");
console.log("endPage")
pdf.save("content.pdf");
$("#pdfContent").removeClass("exporting");
$(".containte_edit .export-pdf span").html("生成PDF");
$(".result-box").show();
$(".result-box .cut-box").show();
$("body").css({"height":"auto","overflow":"auto"});
exporting = false;
setProgress(0);
}else{
console.log("addPage");
console.log("当前不是最后一个resultbox");
pdf.addPage();
$(".result-box:eq("+(resultBoxIndex+1)+")").show().siblings(".result-box").hide();
resultBoxIndex++;
progressIndex++;
setProgress(progressIndex);
newHtmlCanvas(pdf,resultBoxIndex,progressIndex);
}
}
},
//背景设为白色(默认为黑色)
background: "#fff",
useCORS:true
}
)
}
function connectHtmlCanvas(pdf,resultBoxIndex,cutBoxLen,cutBoxIndex,progressIndex){
console.log("cutBoxLen:"+cutBoxLen+"cutBoxIndex:"+cutBoxIndex);
html2canvas(
$(".result-box:eq("+resultBoxIndex+") .cut-box:eq("+cutBoxIndex+")"),
{
dpi: 172,//导出pdf清晰度
onrendered: function (canvas) {
var contentWidth = canvas.width;
var contentHeight = canvas.height;
//一页pdf显示html页面生成的canvas高度;
var pageHeight = contentWidth / 592.28 * 841.89;
// if(pageHeight>2000){
// pageHeight = 2000
// }
//未生成pdf的html页面高度
var leftHeight = contentHeight;
//pdf页面偏移
var position = 20;
//html页面生成的canvas在pdf中图片的宽高(a4纸的尺寸[595.28,841.89])
var imgWidth = 555.28;
var imgHeight = 555.28 / contentWidth * contentHeight;
var pageData = canvas.toDataURL("image/jpeg", 1.0);
//有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)
//当内容未超过pdf一页显示的范围,无需分页
if (leftHeight < pageHeight) {
pdf.addImage(pageData, "JPEG", 20, 30, imgWidth, imgHeight);
} else {
while (leftHeight > 0) {
pdf.addImage(pageData, "JPEG", 20, position, imgWidth, imgHeight)
leftHeight -= pageHeight;
position -= 841.89;
//避免添加空白页
if (leftHeight > 0) {
pdf.addPage();
}
}
}
if(cutBoxIndex==cutBoxLen-1){
console.log("当前为父div里最后一个cut-box");
if(resultBoxIndex==resultBoxLength-1){
console.log("当前为最后一个result-box");
pdf.save("content.pdf");
$("#pdfContent").removeClass("exporting");
$(".containte_edit .export-pdf span").html("生成PDF");
$("body").css({"height":"auto","overflow":"auto"});
$(".result-box").show();
$(".result-box .cut-box").show();
exporting = false;
setProgress(0);
}else{
console.log("当前不是最后一个result-box");
$(".result-box:eq("+(resultBoxIndex+1)+")").show().siblings(".result-box").hide();
resultBoxIndex++;
progressIndex++;
setProgress(progressIndex);
newHtmlCanvas(pdf,resultBoxIndex,progressIndex);
}
}else{
console.log("当前不是父div里最后一个cut-box");
$(".result-box:eq("+resultBoxIndex+") .cut-box:eq("+cutBoxIndex+")").css("display","none");
$(".result-box:eq("+resultBoxIndex+") .cut-box:eq("+(cutBoxIndex+1)+")").css("display","inline-block");
cutBoxIndex++;
pdf.addPage();
progressIndex++;
setProgress(progressIndex);
connectHtmlCanvas(pdf,resultBoxIndex,cutBoxLen,cutBoxIndex,progressIndex)
}
},
//背景设为白色(默认为黑色)
background: "#fff",
useCORS:true
}
)
}
// 设置进度条
function setProgress(progressIndex){
var progress = Math.round((progressIndex/progressLen)*100) +"%";
$(".containte_edit .export-pdf i").css("width",progress);
}
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/53361.html
摘要:比上面的稍微好点,支持了一些方面的东西,具体看这个中文配置参数评价这种方法前端实现,灵活简单,而且在页面还原上是很好的,生成的过程不需要自己操心,页面样式还可控,可以说是非常不错的。 最近要搞前端html转pdf的功能。折腾了两天,略有所收,踩了一些坑,所以做些记录,为后来的兄弟做些提示,也算是回馈社区。经过一番调(sou)研(suo)发现html导出pdf一般有这几种方式,各有各有优...
摘要:比上面的稍微好点,支持了一些方面的东西,具体看这个中文配置参数评价这种方法前端实现,灵活简单,而且在页面还原上是很好的,生成的过程不需要自己操心,页面样式还可控,可以说是非常不错的。 最近要搞前端html转pdf的功能。折腾了两天,略有所收,踩了一些坑,所以做些记录,为后来的兄弟做些提示,也算是回馈社区。经过一番调(sou)研(suo)发现html导出pdf一般有这几种方式,各有各有优...
摘要:比上面的稍微好点,支持了一些方面的东西,具体看这个中文配置参数评价这种方法前端实现,灵活简单,而且在页面还原上是很好的,生成的过程不需要自己操心,页面样式还可控,可以说是非常不错的。 最近要搞前端html转pdf的功能。折腾了两天,略有所收,踩了一些坑,所以做些记录,为后来的兄弟做些提示,也算是回馈社区。经过一番调(sou)研(suo)发现html导出pdf一般有这几种方式,各有各有优...
摘要:最近碰到个需求,需要把当前页面生成,并下载。但这并不是真的截图,而是通过遍历页面结构,收集所有元素信息及相应样式,渲染出。由于只能将它能处理的生成,因此渲染出来的结果并不是与原来一致。 最近碰到个需求,需要把当前页面生成pdf,并下载。弄了几天,自己整理整理,记录下来,我觉得应该会有人需要 :) 项目源码地址:https://github.com/linwalker/... html2...
阅读 1545·2021-11-19 09:40
阅读 3393·2021-11-02 14:47
阅读 4213·2021-10-11 10:58
阅读 3457·2019-08-30 15:54
阅读 3057·2019-08-30 12:50
阅读 2007·2019-08-29 16:54
阅读 741·2019-08-29 15:38
阅读 1475·2019-08-29 15:19