html转换为pdf(打印)(Java版的Puppeteer爬虫框架的使用)

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

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你可以使用 Apache PDFBox 库将 HTML 转换PDF。下面是一个使用 PDFBox 的示例代码: ```java import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import org.apache.pdfbox.pdmodel.PDDocument; import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.PDPageContentStream; import org.apache.pdfbox.pdmodel.PDPageTree; import org.apache.pdfbox.pdmodel.common.PDRectangle; import org.apache.pdfbox.pdmodel.common.PDStream; import org.apache.pdfbox.rendering.PDFRenderer; import org.apache.pdfbox.tools.imageio.ImageIOUtil; public class HTMLtoPDFConverter { public static void main(String[] args) { String htmlFilePath = "path/to/input.html"; String pdfFilePath = "path/to/output.pdf"; // Load HTML file File htmlFile = new File(htmlFilePath); try { // Create a new PDF document PDDocument document = new PDDocument(); PDPage page = new PDPage(PDRectangle.A4); document.addPage(page); // Create a PDPageContentStream object PDPageContentStream contentStream = new PDPageContentStream(document, page); // Load the HTML file into a PDStream FileInputStream inputStream = new FileInputStream(htmlFile); PDStream pdStream = new PDStream(document, inputStream); // Set the media box of the page PDRectangle mediaBox = page.getMediaBox(); contentStream.addRect(mediaBox.getLowerLeftX(), mediaBox.getLowerLeftY(), mediaBox.getWidth(), mediaBox.getHeight()); contentStream.clip(); // Create a PDF renderer PDFRenderer renderer = new PDFRenderer(document); renderer.setDocument(document); // Render the HTML file to PDF renderer.renderPageToStream(renderer.getCurrentPageNo(), pdStream); // Close the content stream and the document contentStream.close(); document.save(new FileOutputStream(pdfFilePath)); document.close(); System.out.println("HTML converted to PDF successfully."); } catch (IOException e) { e.printStackTrace(); } } } ``` 请确保将 `path/to/input.html` 替换为要转换HTML 文件的路径,将 `path/to/output.pdf` 替换为保存生成的 PDF 文件的路径。运行此代码将生成一个包含 HTML 内容的 PDF 文件。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值