zoukankan      html  css  js  c++  java
  • 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。目前这个问题还不知道怎么解决
    

      

  • 相关阅读:
    606. Construct String from Binary Tree
    696. Count Binary Substrings
    POJ 3255 Roadblocks (次短路)
    POJ 2823 Sliding Window (单调队列)
    POJ 1704 Georgia and Bob (博弈)
    UVa 1663 Purifying Machine (二分匹配)
    UVa 10801 Lift Hopping (Dijkstra)
    POJ 3281 Dining (网络流之最大流)
    UVa 11100 The Trip, 2007 (题意+贪心)
    UVaLive 4254 Processor (二分+优先队列)
  • 原文地址:https://www.cnblogs.com/IT-study/p/13738157.html
Copyright © 2011-2022 走看看