前言:

项目开发中遇到了需要将HTML页面的内容导出为一个word文档,所以有了这边随笔。

当然,项目开发又时间有点紧迫,第一时间想到的是用插件,所以百度了下。下面就介绍两个导出word文档的方法。

法一:通过jquery.wordexport.js导出word

备注:兼容IE9以上

大概浏览了下jquery.wordexport.js插件的代码,了解到了通过该插件可以导出文本和图片,而图片首先通过canvas的形式

绘制,文本则需要再依赖FileSaver.js插件,FileSaver.js插件则主要通过H5的文件操作新特性new Blob()和new FileReader()

来实现文本的导出。

插件源码:

FileSaver.js

1 /*FileSaver.js2 * A saveAs() FileSaver implementation.3 * 1.3.24 * 2016-06-16 18:25:195 *6 * By Eli Grey,http://eligrey.com
7 * License: MIT8 *   Seehttps://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md
9  */
10
11 /*global self*/
12 /*jslint bitwise: true, indent: 4, laxbreak: true, laxcomma: true, smarttabs: true, plusplus: true*/
13
14 /*! @sourcehttp://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */
15
16 var saveAs = saveAs ||(function(view) {17         "use strict";18         //IE <10 is explicitly unsupported
19         if (typeof view === "undefined" || typeof navigator !== "undefined" && /MSIE [1-9]\./.test(navigator.userAgent)) {20             return;21 }22         var
23             doc =view.document24         //only get URL when necessary in case Blob.js hasn't overridden it yet
25             , get_URL =function() {26                 return view.URL || view.webkitURL ||view;27 }28             , save_link = doc.createElementNS("http://www.w3.org/1999/xhtml", "a")29             , can_use_save_link = "download" insave_link30             , click =function(node) {31                 var event = new MouseEvent("click");32                 node.dispatchEvent(event);33 }34             , is_safari = /constructor/i.test(view.HTMLElement)35             , is_chrome_ios =/CriOS\/[\d]+/.test(navigator.userAgent)36             , throw_outside =function(ex) {37                 (view.setImmediate ||view.setTimeout)(function() {38                     throwex;39                 }, 0);40 }41             , force_saveable_type = "application/octet-stream"
42         //the Blob API is fundamentally broken as there is no "downloadfinished" event to subscribe to
43             , arbitrary_revoke_timeout = 1000 * 40 //in ms
44             , revoke =function(file) {45                 var revoker =function() {46                     if (typeof file === "string") { //file is an object URL
47 get_URL().revokeObjectURL(file);48                     } else { //file is a File
49 file.remove();50 }51 };52 setTimeout(revoker, arbitrary_revoke_timeout);53 }54             , dispatch = function(filesaver, event_types, event) {55                 event_types =[].concat(event_types);56                 var i =event_types.length;57                 while (i--) {58                     var listener = filesaver["on" +event_types[i]];59                     if (typeof listener === "function") {60                         try{61                             listener.call(filesaver, event ||filesaver);62                         } catch(ex) {63 throw_outside(ex);64 }65 }66 }67 }68             , auto_bom =function(blob) {69                 //prepend BOM for UTF-8 XML and text/* types (including HTML)70                 //note: your browser will automatically convert UTF-16 U+FEFF to EF BB BF
71                 if (/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(blob.type)) {72                     return new Blob([String.fromCharCode(0xFEFF), blob], {type: blob.type});73 }74                 returnblob;75 }76             , FileSaver =function(blob, name, no_auto_bom) {77                 if (!no_auto_bom) {78                     blob =auto_bom(blob);79 }80                 //First try a.download, then web filesystem, then object URLs
81                 var
82                     filesaver = this
83                     , type =blob.type84                     , force = type ===force_saveable_type85 , object_url86                     , dispatch_all =function() {87                         dispatch(filesaver, "writestart progress write writeend".split(" "));88 }89                 //on any filesys errors revert to saving with object URLs
90                     , fs_error =function() {91                         if ((is_chrome_ios || (force && is_safari)) &&view.FileReader) {92                             //Safari doesn't allow downloading of blob urls
93                             var reader = newFileReader();94                             reader.onloadend =function() {95                                 var url = is_chrome_ios ? reader.result : reader.result.replace(/^data:[^;]*;/, 'data:attachment/file;');96                                 var popup = view.open(url, '_blank');97                                 if(!popup) view.location.href =url;98                                 url=undefined; //release reference before dispatching
99                                 filesaver.readyState =filesaver.DONE;100 dispatch_all();101 };102 reader.readAsDataURL(blob);103                             filesaver.readyState =filesaver.INIT;104                             return;105 }106                         //don't create more object URLs than needed
107                         if (!object_url) {108                             object_url =get_URL().createObjectURL(blob);109 }110                         if(force) {111                             view.location.href =object_url;112                         } else{113                             var opened = view.open(object_url, "_blank");114                             if (!opened) {115                                 //Apple does not allow window.open, seehttps://developer.apple.com/library/safari/documentation/Tools/Conceptual/SafariExtensionGuide/WorkingwithWindowsandTabs/WorkingwithWindowsandTabs.html
116                                 view.location.href =object_url;117 }118 }119                         filesaver.readyState =filesaver.DONE;120 dispatch_all();121 revoke(object_url);122 }123 ;124                 filesaver.readyState =filesaver.INIT;125
126                 if(can_use_save_link) {127                     object_url =get_URL().createObjectURL(blob);128 setTimeout(function() {129                         save_link.href =object_url;130                         save_link.download =name;131 click(save_link);132 dispatch_all();133 revoke(object_url);134                         filesaver.readyState =filesaver.DONE;135 });136                     return;137 }138
139 fs_error();140 }141             , FS_proto =FileSaver.prototype142             , saveAs =function(blob, name, no_auto_bom) {143                 return new FileSaver(blob, name || blob.name || "download", no_auto_bom);144 }145 ;146         //IE 10+ (native saveAs)
147         if (typeof navigator !== "undefined" &&navigator.msSaveOrOpenBlob) {148             returnfunction(blob, name, no_auto_bom) {149                 name = name || blob.name || "download";150
151                 if (!no_auto_bom) {152                     blob =auto_bom(blob);153 }154                 returnnavigator.msSaveOrOpenBlob(blob, name);155 };156 }157
158         FS_proto.abort =function(){};159         FS_proto.readyState = FS_proto.INIT = 0;160         FS_proto.WRITING = 1;161         FS_proto.DONE = 2;162
163         FS_proto.error =
164             FS_proto.onwritestart =
165                 FS_proto.onprogress =
166                     FS_proto.onwrite =
167                         FS_proto.onabort =
168                             FS_proto.onerror =
169                                 FS_proto.onwriteend =
170                                     null;171
172         returnsaveAs;173 }(174         typeof self !== "undefined" &&self175         || typeof window !== "undefined" &&window176         || this.content177 ));178 //`self` is undefined in Firefox for Android content script context179 //while `this` is nsIContentFrameMessageManager180 //with an attribute `content` that corresponds to the window
181
182 if (typeof module !== "undefined" &&module.exports) {183     module.exports.saveAs =saveAs;184 } else if ((typeof define !== "undefined" && define !== null) && (define.amd !== null)) {185 define([], function() {186         returnsaveAs;187 });188 }

View Code

jquery.wordexport.js

1 if (typeof jQuery !== "undefined" && typeof saveAs !== "undefined") {2 (function($) {3         $.fn.wordExport =function(fileName) {4             fileName = typeof fileName !== 'undefined' ? fileName : "jQuery-Word-Export";5             var static ={6 mhtml: {7                     top: "Mime-Version: 1.0\nContent-Base:" + location.href + "\nContent-Type: Multipart/related; boundary=\"NEXT.ITEM-BOUNDARY\";type=\"text/html\"\n\n--NEXT.ITEM-BOUNDARY\nContent-Type: text/html; charset=\"utf-8\"\nContent-Location:" + location.href + "\n\n<!DOCTYPE html>\n<html>\n_html_</html>",8                     head: "<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n<style>\n_styles_\n</style>\n</head>\n",9                     body: "<body>_body_</body>"
10 }11 };12             var options ={13                 maxWidth: 624
14 };15             //Clone selected element before manipulating it
16             var markup = $(this).clone();17
18             //Remove hidden elements from the output
19 markup.each(function() {20                 var self = $(this);21                 if (self.is(':hidden'))22 self.remove();23 });24
25             //Embed all images using Data URLs
26             var images =Array();27             var img = markup.find('img');28             for (var i = 0; i < img.length; i++) {29                 //Calculate dimensions of output image
30                 var w =Math.min(img[i].width, options.maxWidth);31                 var h = img[i].height * (w /img[i].width);32                 //Create canvas for converting image to data URL
33                 var canvas = document.createElement("CANVAS");34                 canvas.width =w;35                 canvas.height =h;36                 //Draw image to canvas
37                 var context = canvas.getContext('2d');38                 context.drawImage(img[i], 0, 0, w, h);39                 //Get data URL encoding of image
40                 var uri = canvas.toDataURL("image/png/jpg");41                 $(img[i]).attr("src", img[i].src);42                 img[i].width =w;43                 img[i].height =h;44                 //Save encoded image to array
45                 images[i] ={46                     type: uri.substring(uri.indexOf(":") + 1, uri.indexOf(";")),47                     encoding: uri.substring(uri.indexOf(";") + 1, uri.indexOf(",")),48                     location: $(img[i]).attr("src"),49                     data: uri.substring(uri.indexOf(",") + 1)50 };51 }52
53             //Prepare bottom of mhtml file with image data
54             var mhtmlBottom = "\n";55             for (var i = 0; i < images.length; i++) {56                 mhtmlBottom += "--NEXT.ITEM-BOUNDARY\n";57                 mhtmlBottom += "Content-Location:" + images[i].location + "\n";58                 mhtmlBottom += "Content-Type:" + images[i].type + "\n";59                 mhtmlBottom += "Content-Transfer-Encoding:" + images[i].encoding + "\n\n";60                 mhtmlBottom += images[i].data + "\n\n";61 }62             mhtmlBottom += "--NEXT.ITEM-BOUNDARY--";63
64             //TODO: load css from included stylesheet65
66             //var styles=' /* Font Definitions */@font-face{font-family:宋体;panose-1:2 1 6 0 3 1 1 1 1 1;mso-font-alt:SimSun;mso-font-charset:134;mso-generic-font-family:auto;mso-font-pitch:variable;mso-font-signature:3 680460288 22 0 262145 0;}  @font-face{font-family:"Cambria Math";panose-1:2 4 5 3 5 4 6 3 2 4;mso-font-charset:1;mso-generic-font-family:roman;mso-font-format:other;mso-font-pitch:variable;mso-font-signature:0 0 0 0 0 0;}  @font-face{font-family:"\@宋体";panose-1:2 1 6 0 3 1 1 1 1 1;mso-font-charset:134;mso-generic-font-family:auto;mso-font-pitch:variable;mso-font-signature:3 680460288 22 0 262145 0;}/* Style Definitions */p.MsoNormal, li.MsoNormal, div.MsoNormal{mso-style-unhide:no;mso-style-qformat:yes;mso-style-parent:"";margin:0cm;margin-bottom:.0001pt;mso-pagination:widow-orphan;font-size:14.0pt;font-family:宋体;mso-bidi-font-family:宋体;}p.MsoHeader, li.MsoHeader, div.MsoHeader{mso-style-noshow:yes;mso-style-priority:99;mso-style-link:"页眉 Char";margin:0cm;margin-bottom:.0001pt;text-align:center;mso-pagination:widow-orphan;layout-grid-mode:char;font-size:9.0pt;font-family:宋体;mso-bidi-font-family:宋体;}p.MsoFooter, li.MsoFooter, div.MsoFooter{mso-style-noshow:yes;mso-style-priority:99;mso-style-link:"页脚 Char";margin:0cm;margin-bottom:.0001pt;mso-pagination:widow-orphan;layout-grid-mode:char;font-size:9.0pt;font-family:宋体;mso-bidi-font-family:宋体;}p.MsoAcetate, li.MsoAcetate, div.MsoAcetate{mso-style-noshow:yes;mso-style-priority:99;mso-style-link:"批注框文本 Char";margin:0cm;margin-bottom:.0001pt;mso-pagination:widow-orphan;font-size:9.0pt;font-family:宋体;mso-bidi-font-family:宋体;}span.Char{mso-style-name:"页眉 Char";mso-style-noshow:yes;mso-style-priority:99;mso-style-unhide:no;mso-style-locked:yes;mso-style-link:页眉;font-family:宋体;mso-ascii-font-family:宋体;mso-fareast-font-family:宋体;mso-hansi-font-family:宋体;}span.Char0{mso-style-name:"页脚 Char";mso-style-noshow:yes;mso-style-priority:99;mso-style-unhide:no;mso-style-locked:yes;mso-style-link:页脚;font-family:宋体;mso-ascii-font-family:宋体;mso-fareast-font-family:宋体;mso-hansi-font-family:宋体;}span.Char1{mso-style-name:"批注框文本 Char";mso-style-noshow:yes;mso-style-priority:99;mso-style-unhide:no;mso-style-locked:yes;mso-style-link:批注框文本;font-family:宋体;mso-ascii-font-family:宋体;mso-fareast-font-family:宋体;mso-hansi-font-family:宋体;}p.msochpdefault, li.msochpdefault, div.msochpdefault{mso-style-name:msochpdefault;mso-style-unhide:no;mso-margin-top-alt:auto;margin-right:0cm;mso-margin-bottom-alt:auto;margin-left:0cm;mso-pagination:widow-orphan;font-size:10.0pt;font-family:宋体;mso-bidi-font-family:宋体;}span.msonormal0{mso-style-name:msonormal;mso-style-unhide:no;}.MsoChpDefault{mso-style-type:export-only;mso-default-props:yes;font-size:10.0pt;mso-ansi-font-size:10.0pt;mso-bidi-font-size:10.0pt;mso-ascii-font-family:"Times New Roman";mso-hansi-font-family:"Times New Roman";mso-font-kerning:0pt;}/* Page Definitions */  @page WordSection1{size:595.3pt 841.9pt;margin:72.0pt 90.0pt 72.0pt 90.0pt;mso-header-margin:42.55pt;mso-footer-margin:49.6pt;mso-paper-source:0;}div.WordSection1{page:WordSection1;}';
67
68             var styles="";69
70             //Aggregate parts of the file together
71             var fileContent = static.mhtml.top.replace("_html_", static.mhtml.head.replace("_styles_", styles) + static.mhtml.body.replace("_body_", markup.html())) +mhtmlBottom;72
73             //Create a Blob with the file contents
74             var blob = newBlob([fileContent], {75                 type: "application/msword;charset=utf-8"
76 });77             saveAs(blob, fileName + ".doc");78 };79 })(jQuery);80 } else{81     if (typeof jQuery === "undefined") {82         console.error("jQuery Word Export: missing dependency (jQuery)");83 }84     if (typeof saveAs === "undefined") {85         console.error("jQuery Word Export: missing dependency (FileSaver.js)");86 }87 }

View Code

插件调用:

1 <!DOCTYPE html>
2 <html>
3 <head lang="en">
4     <meta charset="UTF-8">
5     <title>生成word文档</title>
6 </head>
7 <body lang=ZH-CN style='tab-interval:21.0pt'>
8 <div class="word">
9     <p align="center" style="font-size:20pt;font-weight:bold;">JS导出Word文档</p>
10 </div>
11 <input type="button" value="导出word">
12 <script src="https://cdn.bootcss.com/jquery/2.2.4/jquery.js"></script>
13 <script type="text/javascript" src="js/FileSaver.js"></script>
14 <script type="text/javascript" src="js/jquery.wordexport.js"></script>
15 <script>
16     $(function(){17         $("input[type='button']").click(function(event) {18             $(".word").wordExport('生成word文档');19 });20 })21 </script>
22 </body>
23 </html>

直接调用wordExport()接口就可以导出word文档,传的参数为导出的word文件名。

补充:

通过我们常规写的外联样式设置样式是无效的,通过个人的实践发现需要写内联样式才能生效,而单位也需要按照word的配置

单位pt设置。

而jquery.wordexport.js插件是要配置了个style样式让我们补充样式设置的:

但是个人实践了下,设置的样式却无法生效,只能通过内联设置才生效。

截图:

法二:通过百度js模板引擎生成word文档

主要是通过js模板设置对应的标签,然后XDoc.to(baidu.template())导出word,而通过百度js模板引擎的好处是也可以导出PDF文件。

完整demo:

1 <!DOCTYPE html>
2 <html>
3 <head>
4     <metacharset="UTF-8">
5     <scripttype="text/javascript"src="http://www.xdocin.com/xdoc.js"></script>
6     <scripttype="text/javascript"src="http://www.xdocin.com/baiduTemplate.js"></script>
7     <style>
8 .head{
9 font-size:29px;
10 display:block;
11         }
12 .content{
13 display:block;
14         }
15     </style>
16 </head>
17 <body>
18 <inputtype="button"onclick="gen('pdf')"value="生成PDF"/>
19 <inputtype="button"onclick="gen('docx')"value="生成Word"/>
20 <br/>
21 <scriptid="tmpl"type="text/html">
22     <xdoc version="A.3.0">
23         <body>
24         <para heading="1"lineSpacing="28">
25             <text class="head"valign="center"fontName="标宋"fontSize="29"><%=title%></text>
26         </para>
27         <para>
28             <img  src="<%=img%>"sizeType="autosize"/>
29         </para>
30         <para lineSpacing="9">
31             <text class="content"fontName="仿宋"fontSize="18"><%=content%></text>
32         </para>
33         </body>
34     </xdoc>
35 </script>
36 <scriptsrc="https://cdn.bootcss.com/jquery/2.2.4/jquery.js"></script>
37 <scripttype="text/javascript">
38     vartype="docx";//pdf
39     vardata={40 title:"导出"+type+"文件",41 img:"http://www.wordlm.com/uploads/allimg/130101/1_130101000405_1.jpg",42 content:"我这样就可以导出"+type+"格式的文件了,是不是很方便",43 };44     functionrenderTemplate(){45         vartemplate=$("#tmpl").html();46         varhtml=template.replace(/<%=title%>/,data.title)47 .replace(/<%=img%>/,data.img)48 .replace(/<%=content%>/,data.content);49 $("body").append(html);50 }51 renderTemplate();52     functiongen(type) {53 XDoc.to(baidu.template('tmpl', data), type, {},"_blank");54 }55 console.log('http://www.xdocin.com/xml.html');56 </script>
57 </body>
58 </html>  

这里我通过renderTemplate函数叫js模板渲染到HTML中,实现了文本的展示和导出内容的结合。而因为这里导出的word文档是需要特别设置样式的,所以在页面样式展示下我们可以通过添加.class的方式设置。

附部分导出word文档样式设置:

截图:

更多参考:

FileSave.js:https://github.com/eligrey/FileSaver.js

百度导出文档模板:http://www.xdocin.com/xml.html

转载于:https://www.cnblogs.com/aaron-pan/p/7132059.html

将HTML导出生成word文档相关推荐

  1. js将HTML导出生成word文档

    在项目开发中中,遇到将HTML导出生成word文档,刚开始在网上找了很多资料,基本都是jQuery中的插件jquery.wordexport.js,刚开始是不想用这个的,这个要引用另一个插件FileS ...

  2. 用js将HTML文本导出生成word文档

    在项目开发中中,遇到将HTML导出生成word文档,刚开始在网上找了很多资料,基本都是jQuery中的插件jquery.wordexport.js,刚开始是不想用这个的,这个要引用另一个插件FileS ...

  3. Java项目中利用Freemarker模板引擎导出--生成Word文档

    应邀写的一篇文章:Java项目中利用Freemarker模板引擎导出--生成Word文档 资源下载:https://download.csdn.net/download/weixin_41367523 ...

  4. HTML导出生成Word文档

    前言 在某某夜黑风高的一天即将下班的时候,老板召集公司大神们,进行了一个紧急会议,此会议主要目的是老板的客户提出了一些小需求, 有一个前端小 需求,需要将前端HTML导出为Word文档,因为没有做过此 ...

  5. PowerDesigner将PDM导出生成WORD文档

    环境 PowerDesigner15 1.点击Report Temlates 制作模板 2.如果没有模板,单击New图标创建.有直接双击进入. 3.在弹出的类型(Type)对话框中想选择PBM(Phy ...

  6. java导出生成word文档_java使用freemarker 生成word文档

    最近需要做一个导出word的功能, 在网上搜了下, 有用POI,JXL,iText等jar生成一个word文件然后将数据写到该文件中,API非常繁琐而且拼出来的样式也不美观,于是选择了另一种方式--- ...

  7. PowerDesigner将PDM导出生成WORD文档(转)

    今天的温习老知识,是如何将一个PD设计的PDM来导出WORD文档,这是一个非常实用的功能,可以在软件过程的数据库设计文档编写中节省N多时间, 那不废话了,我们就开始今天的讲解吧! 第一步,点击Repo ...

  8. 如何在PowerDesigner将PDM导出生成WORD文档或者html文件

    a)         使用PowerDesigner打开pdm文件 b)         点击Report Temlates 制作模板 点击PowerDesigner菜单栏"Report&q ...

  9. java导出生成word文档并进行下载的方法

    前端html内容展示 <div class="col-md-1 col_top_daochu">导出内容并进行下载 </div> 前端js内容展示 < ...

最新文章

  1. http://www.secrepo.com 安全相关的数据获取源
  2. spring中@Transaction注解解析
  3. cmd静默运行_【已解决】BAT批处理中如何静默执行,在完成后调用MSGBOX?
  4. 如何利用Delphi释放所占的内存
  5. 逻辑漏洞——会话管理问题
  6. g5420 win7集显驱动_台式机装WIN7?雷我已经趟完了
  7. 如何在Ubuntu 16.04上创建多节点MySQL集群(MySQL-Cluster)
  8. STM32 - 高级定时器的设定 - 基础-05 - 输出波形控制 -Complementary outputs and dead-time insertion 相位调整@互补输出和死区控制
  9. penpyxl basic function demo code
  10. LA 3882 And Then There Was One
  11. python多人在线游戏_python实现人接球的小游戏
  12. java arraydeque poll,Java ArrayDeque pollLast()方法
  13. python的ctype调用_Python 使用ctypes调用 C 函数
  14. ADS(Advanced Design system)仿真测试元器件输入阻抗
  15. 频谱泄露和吉布斯现象
  16. Optitrack光学动作捕捉
  17. VC操作Word书签模板
  18. 串行通讯控制器8250
  19. ITEXT7 实现 PDF文档的合并与拆分
  20. Pearson相关分析

热门文章

  1. flink批处理访问mysql_Flink 异步IO访问外部数据(mysql篇)
  2. html代码格式化vscode,vscode 代码格式化
  3. java课程设计总结与思考,你掌握了多少?
  4. 【迁移学习(Transfer L)全面指南】2021年迁移学习发展现状及案例探究
  5. 【深度学习】基于Pytorch的卷积神经网络概念解析和API妙用(二)
  6. 【深度学习入门到精通系列】nnU-Net论文解析
  7. h5 数字变化_前端/h5 D3.js实现根据数据动态更新图形/类似进度实时变化效果
  8. electron 两个窗口如何通信_关于 Electron 进程间通信的一个小小实践
  9. 仅使用python基本语法、即不使用任何模块、编写_微博可以设置“仅半年内可见”!你竟然还不知道???...
  10. python数值型转换字符型_2.6 字符型常量