• html转pdf文件下载之最合理的方法支持中文


    目录

    原始源码出处:

    参考资料:

    正文:

    加上字体赋值行,仅需六行代码就可以实现网页元素转为 PDF 文档。

    完整源码下载:


    原始源码出处:

    https://github.com/parallax/jsPDF  ---->>jsPDF/pdf2.html at master · parallax/jsPDF · GitHub 它原本的花里胡哨的网页例子我就懒得改了,基本是原样使用,只是添加了中文支持,及分页设置。

    参考资料:

    1. JS案例:将前端页面导出为PDF_web15286201346的博客-CSDN博客_js导出pdf  此类多篇文章探讨的,其实是图片插入 pdf 生成文档的方法,这其实失去了 html 转 pdf 的初衷,因为已经丢失了矢量信息,不管精度再高也只是徒增文件大小,毫无意义,不推荐此类方法。

    2. 纯前端生成pdf----js动态获取后台数据生成pdf - 百度文库 

    3. 完美解决jspdf各种乱码问题 - 知乎 这个是解决转矢量 pdf 文档时,中文显示问题,但其代码不完整,无法直接使用。

    正文:

    最近想看看 html 转 pdf 是否可行,查了下,居然有,但是,大多是网页转图片,插入 pdf 的方法,不推荐,于是,由参考资料 1 中,得到 jspdf.js 在 github 的出处,直接去看了下源码,发现,其例子( jsPDF/pdf2.html at master · parallax/jsPDF · GitHub )是不用转图片,可以直接输出矢量 pdf 文档的。

    加上字体赋值行,仅需六行代码就可以实现网页元素转为 PDF 文档。

    因为我的代码是运行在 IIS 下,所以,jspdf 库选择 UMD 版,更多说明都在以下源码内了,多余的废话就不写了:

    1. html>
    2. <html>
    3. <head>
    4. <title>最简单的网页元素转pdf下载例子title>
    5. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    6. <style>
    7. *{
    8. padding:0;
    9. margin: 0;
    10. }
    11. @font-face {
    12. font-family: simfang;/* 应和 .addFont 方法字体名一至 */
    13. src: url('./simfang.ttf');
    14. }
    15. div {
    16. padding:0px;
    17. margin: 0 auto;
    18. border: 0px solid black;
    19. }
    20. .divX{
    21. padding:10px;
    22. }
    23. h1 {
    24. border-bottom: 2px solid white;
    25. }
    26. h2 {
    27. background: #efefef;
    28. padding: 10px;
    29. }
    30. #pdfx{
    31. border: 0;
    32. padding:0;
    33. margin: 0;
    34. background: red;
    35. width:595px;
    36. font-family:simfang;/* 应和 .addFont 方法字体名一至 */
    37. }
    38. .tb1{
    39. width:100%;
    40. }
    41. .tb1 td{
    42. border: 1px solid green;
    43. text-align:center;
    44. }
    45. style>
    46. <script src="./html2canvas.min.js">script>
    47. <script src='./simfang-normal.js'>script>
    48. <script src='./jspdf.umd.min.js'>script>
    49. head>
    50. <body>
    51. <div id="pdfx">
    52. <div class="divX" style="background: green;width:500px;height:821px;">
    53. <div class="divX" style="background: blue; border-color: white;">
    54. <div class="divX" style="background: yellow;">
    55. <div class="divX" style="background: orange;">
    56. <h1>Heading A4幅面一整页h1>
    57. Text that isn't wrapped in anything.
    58. <p>
    59. Followed by some text wrapped in a <b><p> paragraph.b>
    60. p>
    61. <p>
    62. Maybe add a <a href="https://parall.ax/">Parallaxa> or a different style of <a href="http://html2canvas.hertzen.com/"
    63. style='font-weight: 700; color: purple; font-size: 2em'>link with a highlighta>.
    64. p>
    65. <p>
    66. 更多版本源代码请访问:<a href="https://github.com/parallax/jsPDF/" style='font-weight: 700; color: purple; font-size: 2em' id="Parallax"><b>parallax/jsPDFb>a>。
    67. p>
    68. <hr />
    69. <h2>More content 如表格、图片等h2>
    70. <div style="width: 100%; padding: 0;">
    71. <table class="tb1" border="0" cellspacing="0" cellpadding="0">
    72. <tr>
    73. <td>姓名td><td>出生年月td><td>性别td>
    74. tr>
    75. <tr>
    76. <td>张三td><td>2000-1-1td><td>td>
    77. tr>
    78. table>
    79. div>
    80. <div style="width:100%; height: 425px; border-width: 1px; padding: 0;">
    81. <img src="./jspdf.png" style="width:100%;" />
    82. <img src="./jspdf.png" style="width:50%;" />
    83. div>
    84. div>
    85. div>
    86. div>
    87. div>
    88. <div class="divX" style="background: green;width:500px;height:821px;">
    89. <div class="divX" style="background: blue; border-color: white;">
    90. <div class="divX" style="background: yellow;">
    91. <div class="divX" style="background: orange;">
    92. <h1>Heading A4幅面第二页h1>
    93. <p>
    94. 每页高度 841像素.此处因设置了10像素的边框,故需减掉20像素,即高度设为:821px 正好。
    95. p>
    96. <p>
    97. 本来页面高度应为 29.7/2.54*72=841.88976377952像素,但由于四舍五入及取整的关系,超过841像素就会多出一页,因此页面高度只能设为841像素。
    98. p>
    99. <p>
    100. 更多版本源代码请访问:<a href="https://github.com/parallax/jsPDF/" style='font-weight: 700; color: purple; font-size: 2em'><b>parallax/jsPDFb>a>。
    101. p>
    102. <hr />
    103. <h2>更多内容:如表格、图片等h2>
    104. <div style="width: 100%; padding: 0;">
    105. <table class="tb1" border="0" cellspacing="0" cellpadding="0">
    106. <tr>
    107. <td>学历td><td>毕业学校td><td>毕业时间td>
    108. tr>
    109. <tr>
    110. <td>博士后td><td>家里蹲大学td><td>2022-1-1td>
    111. tr>
    112. table>
    113. div>
    114. <div style="width:100%; height: 425px; border-width: 1px; padding: 0;">
    115. <img src="./jspdf.png" style="width:100%;" />
    116. <img src="./jspdf.png" style="width:80%;" />
    117. div>
    118. div>
    119. div>
    120. div>
    121. div>
    122. div>
    123. <script>
    124. /* ps:
    125. 本页代码由 https://github.com/parallax/jsPDF/blob/master/examples/html2pdf/pdf2.html 经更改修正所得,可直接运行于前端 ,无需 Node.js。若含图片输出至 pdf 则须运行于 IIS 。
    126. 仅需 https://html2canvas.hertzen.com/dist/html2canvas.js 、 https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js 和字体文件即可 , 无需 autotable 等多余插件,即可所见即所得原样输出网页对象至 pdf 。
    127. */
    128. var width = 600;
    129. document.body.style.width = width + "px";
    130. //****************引用初始化对象****'https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js'
    131. //const { jsPDF } = window.jspdf; // 这个写法也可以
    132. //jspdf.jsPDF.API.events.push(['addFonts', callAddFont]); // 此位置等效
    133. //const {jsPDF} = jspdf;// 此位置等效
    134. var jsPDF = jspdf.jsPDF;
    135. /* ****************定义添加字体方法一函数 **************
    136. var callAddFont = function () {
    137. this.addFileToVFS('simfang-normal.ttf', font);
    138. this.addFont('simfang-normal.ttf', 'simfang', 'normal');
    139. };
    140. jsPDF.API.events.push(['addFonts', callAddFont]); //**********设置 .html 方法可用字体方法 一
    141. //console.log(jspdf);
    142. */
    143. //**********************-定义最终可用对象******
    144. var pdf = new jsPDF('p', 'pt', 'a4');
    145. /* const pdf = new jsPDF({
    146. orientation: "p",
    147. unit: "pt",
    148. format:"a4"
    149. }); //等效上一句
    150. */
    151. /* **********每页对应网页元素大小分析******************************
    152. //以 px 为单位(unit: "px")则 A4 幅面对应元素宽高为:width:430px;height:611px
    153. //以 pt 为单位(unit: "pt")则 A4 幅面对应元素宽高为:width:595px;height:841px ,可容纳的内容更多
    154. A4纸的尺寸是210mm*297mm,也就是21.0cm*29.7cm,而1英寸=2.54cm,那么当打印分辨率为72像素/英寸时,我们需要做的图片像素尺寸就是:
    155. (21 / 2.54 * 72) * (29.7 / 2.54 * 72);
    156. 即:595像素宽,842像素高:高度修正为 841像素
    157. */
    158. // **********设置 .html 方法可用字体方法二
    159. //var font = "AAAA...."; //此处为 js base64 编码后的字体文件纯文本内容已放置于:simfang-normal.js 便已缓存。 load the *.ttf font file as binary string
    160. /* */
    161. pdf.addFileToVFS('simfang-normal.ttf', font);// simfang-normal.ttf 为虚拟字体名,和 .addFont 参数 1 一至即可
    162. pdf.addFont('simfang-normal.ttf', 'simfang', 'normal');// simfang 为自定义字体名,应和页面中 Css 内设置一至,否则不显示。
    163. /* //**直接设置字体方法仅 .text 方法有效
    164. pdf.addFont("./simfang.ttf", "simfang", "normal"); // simfang.ttf 为真实字体文件名及 URL 相对路径
    165. pdf.setFont("simfang");// simfang 为自定义字体名和上一句一至即可
    166. pdf.setFontSize(40);
    167. pdf.text("中文测试!", 100, 100);//最简单的实例,但不具备使用价值
    168. pdf.save("A4.pdf");
    169. */
    170. /* */
    171. // ** pdf 生成方法一 .html 方法将 pdfx 元素输出为 pdf 文件 "A4.pdf" ,文字为矢量文字,图片直接内嵌源文件,分辨率不受影响,但图片可能会导致生成的 pdf 文件体积较大,推荐方法。
    172. pdf.html(document.getElementById('pdfx'), { // 只有 addFileToVFS 方法添加的字体才能用于 .html 方法
    173. callback: function (pdf) {
    174. //pdf.output('datauristring');// 渲染 pdf
    175. pdf.save("A4.pdf");//自动下载
    176. }
    177. });
    178. /*
    179. // ** pdf 生成方法二,截图填入式。分辨率太低且非矢量文字,放弃,不建议使用。
    180. var shareContent;
    181. shareContent=document.getElementById('pdfx');
    182. html2canvas(shareContent).then(function(canvas) {
    183. var imgUri = canvas.toDataURL("image/png").replace("image/png", "image/octet-stream");
    184. pdf.addImage(imgUri,'png',0,0,595,1682);
    185. pdf.addPage();
    186. pdf.addImage(imgUri,'png',0,-841,595,1682);
    187. pdf.save("A4-2.pdf");//自动下载
    188. }); */
    189. //********* 更多用法请自行探索
    190. script>
    191. body>
    192. html>

    缩小的网页内容,例子为 2 页:

     打开即自动将网页元素转换为 pdf 文件并自动下载:

    下载的含中文且有矢量数据的 pdf 文件:

    生成并下载的 pdf 文件放大至最大级别,依然清晰:

     只有用 .html 方法输出网页元素才能保存矢量数据, .text 方法虽然也是矢量数据,但是不具备实用价值,其余的绘图画表格等方法感觉也是多此一举,既然可以以所见即所得的方式输出完整网页内容,还用得着那些方法做什么?实在不理解 jspdf 作者的设计初衷。

    因为显示中文必须将字体附在网页目录下,第一次访问时会跟 CSS 中设置特定字体那样下载,所以,例子中我选的是一个可用的最小体积的字体,因此部分字符和不常用文字可能不能显示,更换其他字体即可。更换其他字体请看参考资料 3 中的介绍,转换好的字体,我删除了自动生成的代码(html 文件内有代替),只保留了字体赋值那句,其余的都写在 html 里面了。

    还有不清楚的请下载以下完整源码测试:


    完整源码下载:

    html转pdf文件下载之最合理的方法支持中文完整源码-Javascript文档类资源-CSDN下载  , 内含转换好的中文字体及字体转换工具


    最后,必须鄙视一下百度文库改版后难用的阅读界面,模糊不清,要放大了网页才能看清代码,而且复制都收费,原来版本还可以免费复制少量字节的。

  • 相关阅读:
    Byzantine Generals Problem
    机器学习:Xgboost
    ATtiny88初体验(三):串口
    【应用统计学】简单随机抽样的区间估计和样本容量的确定
    Python Flask - 快速构建Web应用详解
    国标视频平台搭建(五)设备接入
    第47节——使用bindActionCreators封装actions模块
    iOS 15.4中添加CSS单元‘dvh‘,解决100%的高度问题。
    ABP - 缓存模块(2)
    uniapp uni.showToast 一闪而过的问题
  • 原文地址:https://blog.csdn.net/jessezappy/article/details/125998024