前言:
项目开发中遇到了需要将HTML页面的内容导出为一个word文档,所以有了这边随笔。
当然,项目开发又时间有点紧迫,第一时间想到的是用插件,所以百度了下。下面就介绍两个导出word文档的方法。
法一:通过jquery.wordexport.js导出word
备注:兼容IE9以上
大概浏览了下jquery.wordexport.js插件的代码,了解到了通过该插件可以导出文本和图片,而图片首先通过canvas的形式
绘制,文本则需要再依赖FileSaver.js插件,FileSaver.js插件则主要通过H5的文件操作新特性new Blob()和new FileReader()
来实现文本的导出。
插件源码:
FileSaver.js
复制代码1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
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*;.*charsets*=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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
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.0nContent-Base: " + location.href + "nContent-Type: Multipart/related; boundary="NEXT.ITEM-BOUNDARY";type="text/html"nn--NEXT.ITEM-BOUNDARYnContent-Type: text/html; charset="utf-8"nContent-Location: " + location.href + "nn<!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-BOUNDARYn";
57 mhtmlBottom += "Content-Location: " + images[i].location + "n";
58 mhtmlBottom += "Content-Type: " + images[i].type + "n";
59 mhtmlBottom += "Content-Transfer-Encoding: " + images[i].encoding + "nn";
60 mhtmlBottom += images[i].data + "nn";
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
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文档?的详细内容,更多请关注靠谱客其它相关文章!
最后
以上就是细心水壶最近收集整理的关于HTML怎么导出生成word文档?的全部内容,更多相关HTML怎么导出生成word文档内容请搜索靠谱客的其他文章。
发表评论 取消回复