html转换为pdf(打印)(Java版的Puppeteer爬虫框架的使用)
Java版的Puppeteer爬虫框架,是一位高手封装的框架,在html转换pdf的效果很不错,源码地址:Puppeteer-java版源码
https://link.zhihu.com/?target=https%3A//github.com/fanyong920/jvppeteer
Puppeteer–这个框架以浏览器内核去访问html页面,使html样式、js可以全部加载完成,得到的一个页面就和浏览器打开的是一样的
下代码其实是我从这个框架(Puppeteer-后端java版)作者源码复制过来改一改就可以使用了,所以仅参考,建议去下载源码下来看看,源码中有很多使用案例可供参考
jar包
<!-- 以浏览器内核访问前端页面,然后将html转为pdf,支持包 -->
<dependency>
<groupId>io.github.fanyong920</groupId>
<artifactId>jvppeteer</artifactId>
<version>1.1.5</version>
</dependency>
使用例
/**
* html转换为pdf
* @param url 网页路径
* @param tagetPath pdf保存路径
* @return
*/
public static boolean convertPdf(String url,String tagetPath,Long loadWaitTime){
Page page = null;
Browser browser = null;
try {
//自动下载,第一次下载后不会再下载
BrowserFetcher.downloadIfNotExist(null);
ArrayList<String> arrayList = new ArrayList<>();
//生成pdf必须在无头模式下才能生效
LaunchOptions options = new LaunchOptionsBuilder().withArgs(arrayList).withHeadless(true).build();
arrayList.add("--no-sandbox");
arrayList.add("--disable-setuid-sandbox");
browser = Puppeteer.launch(options);
page = browser.newPage();
//String url ="http://172.16.41.22/resource/print/index?token=eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE2ODEzMDYyNDIsImxvZ2luX3VzZXJfa2V5IjoiOGM3ZGViNGMtY2FiZC00NzRmLThiYmYtZjFlNzI1MDQ5OTQxIn0.hcQb7MbqdF0m05EuhYZrSxCX33jFpb2hZPx6S2bNz6PBzhzmEucq7VCF1W9UnABvXTmBiqMO-GHOv23OFP2ddQ&fileType=html&path=%2FCES-C919-sx_US-3000100%2FDMC-C919-A-00-40-15-00A-019A-A.XML&printId=41&dmcTitle=Vendor%20List&manualDmc=C919-A-00-40-15-00A-019A-A&issueNumber=006&publicationId=CES-C919-sx_US-3000100&";
page.goTo(url);
// 根据dom判断是否加载完
WaitForSelectorOptions waitForSelectorOptions = new WaitForSelectorOptions();
//超时时间设置为30秒
waitForSelectorOptions.setTimeout(1000*30);
waitForSelectorOptions.setVisible(Boolean.TRUE);
ElementHandle elementHandle = page.waitForSelector(".kd-print__loaded", waitForSelectorOptions);
//待页面加载完成
page.waitFor(StringUtils.toString(loadWaitTime));
PDFOptions pdfOptions = new PDFOptions();
pdfOptions.setPath(tagetPath);
//生成pdf
page.pdf(pdfOptions);
return true;
}catch (Exception e){
e.printStackTrace();
}finally {
try {
if(Objects.nonNull(page)){
page.close();
}
if(Objects.nonNull(browser)){
browser.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
return false;
}
一些问题点说明
1、在上代码例中“page.goTo(url);”这行代码后我加了一个等待操作,其实是因为有些页面太小加载时间较慢,而java代码执行很快,所以需要等一下,不然在转换pdf时,没有拿到数据,pdf就是空的
2、被转换为pdf的html页面需要token(cookie)信息,建议直接拼在路径中,因为我使用框架里加cookie的方式失败了
3、转换出的pdf没有页码,需要增加页码,可参考我另一篇博客https://blog.csdn.net/myiwen_15213620430/article/details/130158170
多个pdf合并为一个
<!-- 合并pdf,支持包 -->
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>2.0.25</version>
</dependency>
/**
* 将多个pdf文件合成一个pdf
* @param list
* @param targetPath 最终生成pdf输出路径
* @return
*/
public String mulFileToOne(List<PrintRecordAddVO> list, String targetPath) {
try {
PDFMergerUtility mergePdf = new PDFMergerUtility();
for (PrintRecordAddVO vo : list) {
// 循环添加要合并的pdf
mergePdf.addSource(new File(vo.getTagetPdfPath()));
}
// 设置合并生成pdf文件名称
mergePdf.setDestinationFileName(targetPath);
// 合并pdf
mergePdf.mergeDocuments(MemoryUsageSetting.setupMainMemoryOnly());
}catch (Exception e){
e.printStackTrace();
return null;
}
return targetPath;
}
在生产环境遇到的问题
com.ruiyun.jvppeteer.exception.TimeoutException: Timed out after 30000 ms while trying to connect to the browser!Chrome output: /usr/app/system/.local-browser/linux-722234/chrome-linux/chrome: error while loading shared libraries: libXss.so.1: cannot open shared object file: No such file or directory
参考:https://blog.csdn.net/weixin_39852491/article/details/114771429
解决方式:
执行命令:find / -name chrome
cd /usr/app/system/.local-browser/linux-722234/chrome-linux/
ldd chrome | grep not
yum install libXScrnSaver* -y
yum install gtk3 -y
中文乱码问题解决(参考)
https://blog.csdn.net/xll20001022/article/details/126849877 Puppeteer