前端生成pdf清晰度不高,模糊,字体放大,自定义字体,加粗样式

前阵子我做了个开源项目——在线编辑简历的小工具(http://www.deartami.com),需要将html页面转换成pdf文件并下载,遇到的一些坑,跟大家分享一下。

清晰度低

开始的思路是这样的,使用html2canvas将html转换成canvas,然后再将canvas转换成图片,将图片保存为pdf格式

html2canvas(target, {  
    scale: 4
}).then(function(canvas) {  
    let context = canvas.getContext('2d');  // 关闭抗锯齿
    context.mozImageSmoothingEnabled = false;
    context.webkitImageSmoothingEnabled = false;
    context.msImageSmoothingEnabled = false;
    context.imageSmoothingEnabled = false;
    PDF.addImage(canvas, 'JPEG', 0, 0, width, height);
    PDF.save('简历.pdf');
});

但是效果非常模糊,查了一番,看到网上的道友们说先放大,于是我将scale值增大到4,虽然效果变好了,但还是远远达不到要求,我需要的是原画质!

于是我换成了jsPDF插件,此插件依赖于html2canvas。

let pdf = new jsPDF({  
    orientation: 'p',  
    unit: 'pt',  
    format: 'a4',  
    precision: '12',  
    putOnlyUsedFonts:false,  
    floatPrecision: "smart" // default is 16
});

pdf.html(target, {  
    html2canvas: {    
        scale: 0.75  
    },  
    callback: function (pdf) {    
        pdf.save('大米简历.pdf');  
    }
});

好了,原画清晰度!非常棒!可以直接访问简历小工具(http://www.deartami.com)体验一番。

字体放大

现在画质解决了 但是我发现文字都被放大了~
~阿噢~
image.png

怎么整?

查了一下jsPDF的issues,看到有一个解答正好是我需要的(issues/2632):

image.png

pdf.html(target, {  
    html2canvas: {    
        scale: 0.75  
    },  
    callback: function (pdf) {    
        pdf.save('大米简历.pdf');  
    }
});

我将scale参数设为0.75就正常了。

不支持中文

然而,我很快就发现,这种解决方案不支持中文啊,我滴个神啊~

怎么办?

能咋办?搞呗~我就哼哧哼哧地爬起来各种翻文档,原来在README.md有说明:

image.png

要自己加字体。好吧......

我使用的是思源字体:https://github.com/Pal3love/S...

使用官方提供的fontconverter:https://rawgit.com/MrRio/jsPD...
将.ttf文件转换成.js文件sourcehansanscn-normal-normal.js。注意⚠️:.ttf的文件名要先改成小写,否则无效

这个字体包很大,为了不影响首屏的加载速度,所以引入的时候我独自打包了。

import(/*  webpackChunkName: "sourcehansanscnNormal"*/'@/util/sourcehansanscn-normal-normal').then((source) => {  source.SourceHanSansCN();});
.pdfcontent{    font-family:'SourceHanSansCN-Normal' /*pdf转换插件不能识别中文*/}

注意⚠️:不要使用商用字体哦~

字体加粗

好了,似乎很很完美了~Y~

然鹅,还是有问题,打印出来的pdf不能识别加粗字体,也就是font-weight: bold设置无效。

继续查找issues,无解,只能引入两种不同的字体包,一种是正常的,一种是加粗的,单独设置font-family属性

.pdfcontent{    
    font-family:'SourceHanSansCN-Normal' /*pdf转换插件不能识别中文*/
}

.pdfcontent strong,
.pdfcontent h1,
.pdfcontent h2,
.pdfcontent h3,
.pdfcontenth4{  
    font-family: 'sourcehansanscn-medium';
}

到此为止~一切真的完美了~编译通过就等上线啦~嘿嘿嘿~

压缩打包运行npm run build~哒哒哒哒~

~哒~

~哒~

~哒~

运行失败,内存溢出啦......==!!!

内存溢出

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory

哇,那两个字体文件太大了,我就说嘛!

我就骂骂咧咧地打开vue-cli的issues,还真有解决方案:issues/1453

修改package.json中的script,将max\_old\_space\_size增大至4096,你可根据自己的文件修改大小值哈~

"build": "node --max\_old\_space\_size=4096 node\_modules/@vue/cli-service/bin/vue-cli-service.js build --open"

终于~到了这里~一切就绪~我可以上线啦~

关于源码,后续我会放到https://github.com/aBigRice/r...

不过在写这篇文章的时候我还没有上传~~~~

嘿嘿~~

那你关注我嘛~~~~~

你可能感兴趣的:(前端,pdf)