使用 Docx.js 在 JavaScript 中生成 Word 文档?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15899883/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 02:30:28  来源:igfitidea点击:

Generate a Word document in JavaScript with Docx.js?

javascriptms-worddocx

提问by Peter

I am trying to use docx.jsto generate a Word document but I can't seem to get it to work.

我正在尝试使用docx.js来生成 Word 文档,但我似乎无法让它工作。

I copied the raw code into the Google Chrome console after amending line 247 to fix a "'textAlign' undefined error"

在修改第 247 行以修复“'textAlign' 未定义错误”后,我将原始代码复制到 Google Chrome 控制台中

if (inNode.style && inNode.style.textAlign){..}

Which makes the function convertContentavailable. The result of which is an Object e.g.

这使得该功能convertContent可用。其结果是一个对象,例如

JSON.stringify( convertContent($('<p>Word!</p>)[0]) )

Results in -

结果是 -

"{"string":
      "<w:body>
            <w:p>
                <w:r>
                    <w:t xml:space=\"preserve\">Word!</w:t>
                </w:r>
            </w:p>
       </w:body>"
 ,"charSpaceCount":5
 ,"charCount":5,
 "pCount":1}"

I copied

我复制的

<w:body>
    <w:p>
        <w:r>
            <w:t xml:space="preserve">Word!</w:t>
        </w:r>
    </w:p>
</w:body>

into Notepad++ and saved it as a file with an extension of 'docx' but when I open it in MS Word but it says 'cannot be opened because there is a problem with the contents'.

到 Notepad++ 并将其保存为扩展名为“docx”的文件,但是当我在 MS Word 中打开它时,它说“无法打开,因为内容有问题”。

Am I missing some attribute or XML tags or something?

我是否缺少某些属性或 XML 标签或其他东西?

采纳答案by edi9999

This code can't work on a JSFiddle because of the ajaxCalls to local files (everything that is in the blankfolder), or you should enter all files in ByteArray format and use the jsFiddleecho API: http://doc.jsfiddle.net/use/echo.html

由于对本地文件(blank文件夹中的所有内容)的 ajaxCalls,此代码无法在 JSFiddle 上运行,或者您应该以 ByteArray 格式输入所有文件并使用jsFiddleecho API:http: //doc.jsfiddle.net/使用/echo.html

回答by edi9999

You can generate a Docx Document from a template using docxtemplater(library I have created).

您可以使用docxtemplater(我创建的库)从模板生成 Docx 文档。

It can replace tags by their values (like a template engine), and also replace images in a paid version.

它可以通过标签的值(如模板引擎)替换标签,也可以替换付费版本中的图像。

Here is a demo of the templating engine: https://docxtemplater.com/demo/

这是模板引擎的演示:https: //docxtemplater.com/demo/

回答by adam0101

I know this is an older question and you already have an answer, but I struggled getting this to work for a day, so I thought I'd share my results.

我知道这是一个较旧的问题,您已经有了答案,但我努力让它工作了一天,所以我想我会分享我的结果。

Like you, I had to fix the textAlignbug by changing the line to this:

像您一样,我必须textAlign通过将行更改为以下内容来修复错误:

if (inNode.style && inNode.style.textAlign)

Also, it didn't handle HTML comments. So, I had to add the following line above the check for a "#text" node in the forloop:

此外,它不处理 HTML 注释。因此,我必须在for循环中检查“#text”节点的上方添加以下行:

if (inNodeChild.nodeName === '#comment') continue;

To create the docx was tricky since there is absolutely no documentation on this thing as of yet. But looking through the code, I see that it is expecting the HTML to be in a File object. For my purposes, I wanted to use the HTML I rendered, not some HTML file the user has to select to upload. So I had to trick it by making my own object with the same property that it was looking for and pass it in. To save it to the client, I use FileSaver.js, which requires a blob. I included this functionthat converts base64 into a blob. So my code to implement it is this:

创建 docx 很棘手,因为到目前为止还没有关于这件事的文档。但是查看代码,我发现它期望 HTML 位于 File 对象中。出于我的目的,我想使用我呈现的 HTML,而不是用户必须选择上传的某些 HTML 文件。所以我不得不通过使用它正在寻找的相同属性创建我自己的对象并将其传入来欺骗它。为了将它保存到客户端,我使用FileSaver.js,它需要一个 blob。我包含了这个将 base64 转换为 blob 的函数。所以我实现它的代码是这样的:

var result = docx({ DOM: $('#myDiv')[0] });
var blob = b64toBlob(result.base64, "application/vnd.openxmlformats-officedocument.wordprocessingml.document");
saveAs(blob, "test.docx");

In the end, this would work for simple Word documents, but isn't nearly sophisticated for anything more. I couldn't get any of my styles to render and I didn't even attempt to get images working. I've since abandoned this approach and am now researching DocxgenJSor some server-side solution.

最后,这适用于简单的 Word 文档,但对于更多的文档来说几乎不复杂。我无法渲染任何样式,我什至没有尝试让图像正常工作。我已经放弃了这种方法,现在正在研究DocxgenJS或一些服务器端解决方案。

回答by Joshua Smith

You are doing the correct thing codewise, but your file is not a valid docx file. If you look through the docx()function in docx.js, you will see that a docx file is actually a zip containing several xml files.

您正在按代码做正确的事情,但您的文件不是有效的 docx 文件。如果您查看docx()docx.js 中的函数,您会看到一个 docx 文件实际上是一个包含多个 xml 文件的 zip。

回答by Victor Xie

I am using Open Xml SDK for JavaScript.

我正在为 JavaScript 使用 Open Xml SDK。

http://ericwhite.com/blog/open-xml-sdk-for-javascript/

http://ericwhite.com/blog/open-xml-sdk-for-javascript/

Basically, on web server, I have a empty docx file as new template. when user in browser click new docx file, I will retrieve the empty docx file as template, convert it to BASE64 and return it as Ajax response.

基本上,在网络服务器上,我有一个空的 docx 文件作为新模板。当用户在浏览器中单击新的 docx 文件时,我将检索空的 docx 文件作为模板,将其转换为 BASE64 并将其作为 Ajax 响应返回。

in client scripts, you convert the BASE64 string to byte array and using openxmlsdk.js to load the byte array as an javascript OpenXmlPackage object.

在客户端脚本中,您将 BASE64 字符串转换为字节数组并使用 openxmlsdk.js 将字节数组加载为 javascript OpenXmlPackage 对象。

once you have the package loaded, you can use regular OpenXmlPart to create a real document. (inserting image, creating table/row ).

一旦你加载了包,你就可以使用常规的 OpenXmlPart 创建一个真正的文档。(插入图像,创建表/行)。

the last step is stream it out to end user as a document. this part is security related. in my code I send it back to webserver and gets saved temporarily. and prepare a http response to notify end user to download it.

最后一步是将其作为文档流式传输给最终用户。这部分是安全相关的。在我的代码中,我将它发送回网络服务器并临时保存。并准备一个 http 响应以通知最终用户下载它。

Check the URL above, there are useful samples of doing this in JavaScript.

检查上面的 URL,有在 JavaScript 中执行此操作的有用示例。