前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >RestPack Java实现Html转PDF文件

RestPack Java实现Html转PDF文件

作者头像
用户1518699
发布2020-09-28 10:59:21
1.6K0
发布2020-09-28 10:59:21
举报
文章被收录于专栏:nice_每一天

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

以下为解决方案调研

https://cloud.tencent.com/developer/article/1997197

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

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

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

官网https://restpack.io/

解决思路

代码语言:javascript
复制
1.将一个可访问的H5URL转换为Pdf文件

2.将Pdf文件写到页面

H5URL转换为Pdf文件

代码语言:javascript
复制
 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导出文档入参

代码语言:javascript
复制
 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导出文档返回参数

代码语言:javascript
复制
 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 }

将文件写到页面

代码语言:javascript
复制
 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     }

使用事项

代码语言:javascript
复制
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。目前这个问题还不知道怎么解决
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-09-27 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 解决思路
  • H5URL转换为Pdf文件
  • H5URL导出文档入参
  • H5URL导出文档返回参数
  • 将文件写到页面
  • 使用事项
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档