Maison  >  Article  >  interface Web  >  Comment exporter du HTML pour générer un document Word ?

Comment exporter du HTML pour générer un document Word ?

零下一度
零下一度original
2018-05-18 13:41:0523707parcourir

Avant-propos :

Lors du développement du projet, j'ai rencontré le besoin d'exporter le contenu de la page HTML dans un document Word, j'ai donc imaginé ceci essai.

Bien sûr, le temps de développement du projet était un peu serré, et la première chose à laquelle j'ai pensé était d'utiliser des plug-ins, alors Baidu y a jeté un coup d'œil. Voici deux méthodes pour exporter des documents Word.

Méthode 1 : Exporter le mot via jquery.wordexport.js

Remarques : Compatible avec IE9 et supérieur

Parcourir le code du plug-in jquery.wordexport.js, J'ai appris que grâce à ce plug-in, vous pouvez exporter du texte et des images, et les images sont d'abord dessinées sous forme de canevas

, et le texte doit s'appuyer sur le plug-in FileSaver.js. js utilise principalement la nouvelle fonctionnalité d'opération de fichier de H5 new Blob() et new FileReader()

pour implémenter l'exportation de texte.

Code source du plug-in :

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&#39;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&#39;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:[^;]*;/, &#39;data:attachment/file;&#39;); 
  96                                 var popup = view.open(url, &#39;_blank&#39;); 
  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&#39;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 }

Afficher le code

jquery.wordexport.js

 1 if (typeof jQuery !== "undefined" && typeof saveAs !== "undefined") { 
 2     (function($) { 
 3         $.fn.wordExport = function(fileName) {
 4             fileName = typeof fileName !== &#39;undefined&#39; ? 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(&#39;:hidden&#39;))
 22                     self.remove();
 23             });
 24 
 25             // Embed all images using Data URLs
 26             var images = Array();
 27             var img = markup.find(&#39;img&#39;);
 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(&#39;2d&#39;);
 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=&#39; /* 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;}&#39;;
 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 }

Afficher le code

Appel du plug-in :

 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=&#39;tab-interval:21.0pt&#39;> 
 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=&#39;button&#39;]").click(function(event) {
 18             $(".word").wordExport(&#39;生成word文档&#39;);
 19         });
 20     })
 21 </script>
 22 </body>
 23 </html>

Appelez directement l'interface wordExport() pour exporter le document Word, et les paramètres transmis sont le nom du fichier Word exporté.

Supplément :

Il n'est pas valide de définir le style via notre écriture de style externe régulière. Grâce à une pratique personnelle, j'ai découvert qu'il est nécessaire d'écrire un style en ligne pour prendre effet, et l'unité également. doit suivre la configuration du paramètre word

Unit pt.

Le plug-in jquery.wordexport.js est configuré avec un style qui nous permet de compléter les paramètres de style :

Mais après pratique personnelle, j'ai définir Le style ne peut pas prendre effet, il ne peut prendre effet que via un paramètre en ligne.

Capture d'écran :

Méthode 2 : Générer un document Word via le moteur de modèle Baidu js

Définir principalement la correspondance via le modèle js balise, puis XDoc.to(baidu.template()) exporte le mot, et l'avantage d'utiliser le moteur de modèles Baidu js est qu'il peut également exporter des fichiers PDF.

Démo complète :

 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(&#39;pdf&#39;)" value="生成PDF"/>
 19 <input type="button" onclick="gen(&#39;docx&#39;)" 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(&#39;tmpl&#39;, data), type, {}, "_blank");
 54     }
 55     console.log(&#39;&#39;);
 56 </script>
 57 </body>
 58 </html>

Ici, j'appelle le modèle js pour le rendu en HTML via la fonction renderTemplate, réalisant la combinaison de l'affichage du texte et du contenu exporté. Et comme le document Word exporté ici doit être spécialement stylé, nous pouvons le définir en ajoutant .class sous l'affichage du style de page.

Vous trouverez ci-joint quelques paramètres de style de document Word exportés :

Capture d'écran :

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Article précédent:Comprendre HTML5 WebSocketArticle suivant:Comprendre HTML5 WebSocket