首页 > 编程 > HTML > 正文

HTML怎么导出生成word文档?

2020-03-24 18:13:26
字体:
来源:转载
供稿:网友
前言:

项目开发中遇到了需要将html' target='_blank'>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.js    2  * A saveAs() FileSaver implementation.    3  * 1.3.2    4  * 2016-06-16 18:25:19    5  *    6  * By Eli Grey,     7  * License: MIT    8  *   See     9  */   10    11 /*global self */   12 /*jslint bitwise: true, indent: 4, laxbreak: true, laxcomma: true, smarttabs: true, plusplus: true */   13    14 /*! @source  */   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.document   24         // 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("", "a")   29             , can_use_save_link = "download" in save_link   30             , 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                     throw ex;   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                 return blob;   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.type   84                     , force = type === force_saveable_type   85                     , object_url   86                     , 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 = new FileReader();   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, see   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.prototype  142             , 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             return function(blob, name, no_auto_bom) {  149                 name = name || blob.name || "download";  150   151                 if (!no_auto_bom) {  152                     blob = auto_bom(blob);  153                 }  154                 return navigator.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         return saveAs;  173     }(  174         typeof self !== "undefined" && self  175         || typeof window !== "undefined" && window  176         || this.content  177     ));  178 // `self` is undefined in Firefox for Android content script context  179 // while `this` is nsIContentFrameMessageManager  180 // 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         return saveAs;  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 stylesheet 65  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, p.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, p.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, p.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, p.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, p.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;}p.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 = new Blob([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 <p class="word">  9     <p align="center" style="font-size:20pt;font-weight:bold;">JS导出Word文档</p> 10 </p> 11 <input type="button" value="导出word"> 12 <script src="https://cdn.bootcss.com/jquery/2.2.4/jquery.js?1.1.11"></script> 13 <script type="text/javascript" src="js/FileSaver.js?1.1.11"></script> 14 <script type="text/javascript" src="js/jquery.wordexport.js?1.1.11"></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     <meta charset="UTF-8">  5     <script type="text/javascript" src="www.xdocin.com/xdoc.js?1.1.11"></script>  6     <script type="text/javascript" src="http://www.xdocin.com/baiduTemplate.js?1.1.11"></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 <input type="button" onclick="gen('pdf')" value="生成PDF"/> 19 <input type="button" onclick="gen('docx')" value="生成Word"/> 20 <br/> 21 <script id="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 <script src="https://cdn.bootcss.com/jquery/2.2.4/jquery.js?1.1.11"></script> 37 <script type="text/javascript"> 38     var type="docx";//pdf 39     var data = { 40         title: "导出"+type+"文件", 41         img: "", 42         content: "我这样就可以导出"+type+"格式的文件了,是不是很方便", 43     }; 44     function renderTemplate(){ 45         var template=$("#tmpl").html(); 46         var html=template.replace(/<%=title%>/,data.title) 47                 .replace(/<%=img%>/,data.img) 48                 .replace(/<%=content%>/,data.content); 49         $("body").append(html); 50     } 51     renderTemplate(); 52     function gen(type) { 53         XDoc.to(baidu.template('tmpl', data), type, {}, "_blank"); 54     } 55     console.log(''); 56 </script> 57 </body> 58 </html>

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

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

截图:

以上就是HTML怎么导出生成word文档?的详细内容,更多请关注 其它相关文章!

郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表