서문:
프로젝트 개발 중에 HTML 페이지의 내용을 워드 문서로 내보내야 할 필요성을 만나 이 에세이를 생각해냈습니다.
물론 프로젝트 개발 시간이 좀 빡빡해서 가장 먼저 생각난 것이 플러그인을 활용하는 것이었기 때문에 바이두를 살펴봤습니다. Word 문서를 내보내는 두 가지 방법은 다음과 같습니다.
참고: IE9 이상과 호환됨
jquery.wordexport.js 플러그인의 코드를 탐색하면서 이 플러그인을 통해 텍스트와 그림을 내보낼 수 있다는 것을 알게 되었습니다. 캔버스 형태로 텍스트를 그리려면 FileSaver.js 플러그인을 사용해야 합니다. FileSaver.js 플러그인은 주로 H5의 새로운 파일 작업 기능인 new Blob() 및 텍스트를 내보내는 새로운 FileReader()
플러그인 소스 코드: iFilesaver.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 }
jqury.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 }
플러그인
: : :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>
유닛pt.
jquery.wordexport.js 플러그인은 스타일 설정을 보완할 수 있는 스타일로 구성되어 있습니다.
단, 개인 연습 후에는 설정된 스타일이 적용되지 않고 인라인을 통해서만 적용됩니다. 설정.
스크린샷:
방법 2: Baidu js 템플릿 엔진을 통해 워드 문서 생성
전체 데모:
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>
여기에서는 js 템플릿을 호출하여 renderTemplate 기능을 통해 HTML로 렌더링하여 텍스트 표시와 내보낸 콘텐츠의 조합을 실현합니다. 그리고 여기에 내보낸 워드 문서는 특별한 스타일이 필요하기 때문에 페이지 스타일 표시 아래에 .class를 추가하여 설정할 수 있습니다.
내보낸 일부 단어 문서 스타일 설정이 첨부되어 있습니다.
스크린샷:
위 내용은 Word 문서를 생성하기 위해 HTML을 내보내는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!