• RestPack Java实现Html转PDF文件


    最近公司需要将前端一个图表统计导出为pdf。前端导出显示的pdf还是可以的,但是将会导致页面不可用与卡死状态。所以由后端寻找解决方案。

    以下为解决方案调研

    https://www.cnblogs.com/IT-study/p/13706690.html

    由于自己开发一个公共的导出pdf功能比较费时费力,而且导出过程中也遇到了各种样式问题。考虑再三决定使用第三方导出来解决这个问题。

    好处:接入简单给个H5url即可,无需要考虑导出中遇到的写出的样式与排版问题

    坏处:无法做到完全自定义。拿restPack举例子 ,导出长图无法自定义宽度,目前导出有1280px宽度,业务需要手机预览宽度只要 A6纸的规格即可。也可能可以通过js、css参数去解决,我没找到对应的方法。

    官网https://restpack.io/

    解决思路

    1.将一个可访问的H5URL转换为Pdf文件
    
    2.将Pdf文件写到页面

    H5URL转换为Pdf文件

     1 @Component
     2 public class H5UrlExportPdf {
     3 
     4 
     5     @Value("${restpack.token}")
     6     private String token = "HA5jLSVtSnjl3fmlhPgTg7rPRE4OnywDvh1CrbanXmpBvNqA";
     7 
     8 
     9     /**
    10      * https://restpack.io/html2pdf/docs
    11      */
    12     public ReturnRestPackPdf exportPdf(RestPackPdfParameters restpackPdfParameters) throws IOException {
    13 
    14 
    15         ReturnRestPackPdf returnRestPackPdf;
    16 
    17         //请求URL
    18         String reqUrl = "https://restpack.io/api/html2pdf/v6/convert";
    19         StringBuilder stringBuilder = new StringBuilder();
    20 
    21         //地址需要encode
    22         String firstP = "url";
    23         stringBuilder.append(firstP).append("=").append(restpackPdfParameters.getUrl());
    24 
    25         Map<String, String> describe = BeanHelper.describe(restpackPdfParameters);
    26         describe.forEach((name, val) -> {
    27 
    28             if (!firstP.equalsIgnoreCase(name)) {
    29                 stringBuilder.append("&").append(name).append("=").append(val);
    30             }
    31         });
    32 
    33         System.out.println(stringBuilder.toString());
    34 
    35         byte[] postData = stringBuilder.toString().getBytes(StandardCharsets.UTF_8);
    36         HttpURLConnection con = null;
    37 
    38         try {
    39 
    40             URL myUrl = new URL(reqUrl);
    41             con = (HttpURLConnection) myUrl.openConnection();
    42 
    43             con.setDoOutput(true);
    44             con.setRequestMethod("POST");
    45             con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
    46             con.setRequestProperty("x-access-token", token);
    47 
    48             try (DataOutputStream wr = new DataOutputStream(con.getOutputStream())) {
    49                 wr.write(postData);
    50             }
    51 
    52             StringBuilder content;
    53 
    54             try (BufferedReader in = new BufferedReader(
    55                     new InputStreamReader(con.getInputStream()))) {
    56 
    57                 String line;
    58                 content = new StringBuilder();
    59 
    60                 while ((line = in.readLine()) != null) {
    61                     content.append(line);
    62                     content.append(System.lineSeparator());
    63                 }
    64             }
    65 
    66             returnRestPackPdf = JSONObject.parseObject(content.toString(), ReturnRestPackPdf.class);
    67 
    68         } finally {
    69             if (con != null) {
    70                 con.disconnect();
    71             }
    72         }
    73 
    74         return returnRestPackPdf;
    75     }
    76 
    77 
    78 }

    H5URL导出文档入参

     1 @Data
     2 public class RestPackPdfParameters implements Serializable{
     3 
     4     private static final long serialVersionUID = 1L;
     5 
     6 
     7     /**
     8      * 需要导出文档H5URL
     9      * The URL of web page, including the protocol that you want to capture.
    10      * Example: http://example.com
    11      */
    12     private String url;
    13 
    14 
    15     /**
    16      * Return a JSON response with the resulting image's URL instead of the image itself.
    17      * Default: false
    18      */
    19     private Boolean json = true;
    20 
    21 
    22     /**
    23      * Page size for created document
    24      *
    25      * Default: Full
    26      * Pattern: A0 | A1 | A2 | A3 | A4 | A5 | A6 | Legal | Letter | Tabloid | Ledger | Full
    27      *
    28      * Legal:width 816 多张图片阶段
    29      * Letter:width 816 多张图片阶段
    30      * Tabloid:width 1056 多张图片阶段
    31      * Ledger:width 1632 多张图片阶段
    32      * Full:width 1280 一张图片
    33      */
    34     private String pdf_page="Full";
    35 
    36     public RestPackPdfParameters() {
    37     }
    38 
    39     public RestPackPdfParameters(String url) {
    40         this.url = url;
    41     }
    42 }

    H5URL导出文档返回参数

     1 @Data
     2 public class ReturnRestPackPdf implements Serializable{
     3 
     4     private static final long serialVersionUID = 1L;
     5 
     6 
     7     private Boolean cached;
     8     private String content_type;
     9     /** pdf文件类型地址 */
    10     private String file;
    11     private Integer height;
    12     private Integer width;
    13     /** pdf图片类型地址 */
    14     private String image;
    15     private String length;
    16     private String remote_status;
    17     private String run_time;
    18     private String url;
    19 
    20 }

    将文件写到页面

     1     private void downFileHtml(String name, @RequestParam(value = "fileUrl", required = false) String fileUrl, HttpServletResponse response, Boolean useName) {
     2         BufferedInputStream bis = null;
     3         BufferedOutputStream bos = null;
     4         OutputStream output = null;
     5         try {
     6             log.info("downLoadFileStart:" + fileUrl);
     7             response.setContentType("application/octet-stream; charset=UTF-8");
     8             if (useName) {
     9 
    10             } else {
    11                 String ext = fileUrl.substring(fileUrl.lastIndexOf("."));
    12                 name = name + ext;
    13                 name = URLDecoder.decode(name, "UTF-8");
    14             }
    15 
    16             response.setHeader("Content-Disposition", "attachment;fileName="" + new String(name.getBytes("GBK"), "ISO8859-1") + """);
    17 
    18             URL url = new URL(fileUrl);
    19             bis = new BufferedInputStream(url.openStream());
    20             output = response.getOutputStream();
    21             bos = new BufferedOutputStream(output);
    22             log.info("downLoadFileCopyStream:" + fileUrl);
    23             byte[] buff = new byte[2048];
    24             int bytesRead;
    25             while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
    26                 log.info("downLoadFileCopyStreamDetail:" + bytesRead);
    27                 bos.write(buff, 0, bytesRead);
    28             }
    29             log.info("downLoadFileEnd:" + fileUrl);
    30         } catch (Exception e) {
    31             log.error("downLoadFileError:" + fileUrl + ":error:" + e.getMessage());
    32             e.printStackTrace();
    33         } finally {
    34             try {
    35                 if (bos != null) {
    36                     bos.flush();
    37                     bos.close();
    38                 }
    39                 if (bis != null) {
    40                     bis.close();
    41                 }
    42                 if (output != null) {
    43                     output.close();
    44                 }
    45             } catch (IOException e) {
    46                 e.printStackTrace();
    47             }
    48         }
    49     }

    使用事项

    1.url 为转换pdf的页面地址,改地址必须能直接访问(无登录功能)
    
    2.pdf_page 有几个页面规格 A0 | A1 | A2 | A3 | A4 | A5 | A6 | Legal | Letter | Tabloid | Ledger | Full 。Full可导出一张长图,但是宽度不可定。其他的规格与A4类似,导出的是多张图片。
    
    3.pdf_width 、pdf_height 可自定义页面规格。一旦pdf_page设置,pdf_width pdf_height必须为空。
    
    4.一旦付费成功 css、js 可进行调节生成pdf文件产生的样式问题。
    
    5.我们需要导出一整张图片,但是一整张图的宽度不可自定义。导出的宽度为1280px,手机上显示只需要800px。目前这个问题还不知道怎么解决
    

      

  • 相关阅读:
    jquery validate使用总结
    javascript 学习笔记
    jquery easyui 学习总结
    javascript模式及javascript学习终极篇
    javascript学习笔记基础
    javascript学习笔记常见问题及技巧
    一道ITAT的题(C语言实现)
    JAVA实现约瑟夫算法
    JAXWS例子
    practical java笔记(实践1~5)
  • 原文地址:https://www.cnblogs.com/IT-study/p/13738157.html
Copyright © 2020-2023  润新知