在过去的几天里,我一直在尝试创建一个脚本,它将1)从Word文档中提取XML,2)修改该XML,3)使用新的XML来创建和保存一个新的Word文档。在许多stackoverflow用户的帮助下,我最终找到了看起来非常有前途的代码。这里是:
import zipfile
import os
import tempfile
import shutil
def getXml(docxFilename):
zip = zipfile.ZipFile(open(docxFilename,"rb"))
xmlString= zip.read("word/document.xml").decode("utf-8")
return xmlString
def createNewDocx(originalDocx,xmlString,newFilename):
tmpDir = tempfile.mkdtemp()
zip = zipfile.ZipFile(open(originalDocx,"rb"))
zip.extractall(tmpDir)
with open(os.path.join(tmpDir,"word/document.xml"),"w") as f:
f.write(xmlString)
filenames = zip.namelist()
zipCopyFilename = newFilename
with zipfile.ZipFile(zipCopyFilename,"w") as docx:
for filename in filenames:
docx.write(os.path.join(tmpDir,filename),filename)
shutil.rmtree(tmpDir)
getXml
从docxFilename
提取XML作为字符串。createNewDocx
获取原始Word文档并将其XML替换为xmlString
,这是原始XML的修改版本,并将生成的Word文档另存为newFilename
。在
为了检查脚本是否按预期工作,我首先创建了一个测试文档(“测试.docx)并运行createNewDocx("test.docx",getXml("test.docx"),"test2.docx")
。如果一切都按预期运行,那么这应该创建一个完全相同的测试.docx另存为test2.docx。确实如此。在
然后,我将测试文档变得更加详细,并尝试修改它。而且剧本仍然有效!在
然后我自信地将我的脚本应用到我真正感兴趣的Word文档中:template.docx
。我运行了createNewDocx("template.docx",getXml("template.docx"),"template2.docx")
,希望脚本将生成docx.docx模板但命名为template2.docx。不幸的是,新的Word文档无法打开;显然XML中有一个非法字符。在
我真的不明白为什么我的代码对我的测试文档有效,但对我的实际文档无效。我会发帖的模板.docx的XML,但它包含个人信息。两者之间的一个重要区别测试.docx以及模板.docx是这样吗模板.docx是用法语写的,因此包含特殊字符,如重音,而且撇号看起来也不同。我不知道这是否是我的麻烦,但我没有其他的想法。在
问题是您不小心更改了
template2.docx
中word/document.xml
上的编码。word/document.xml
(来自template.docx
)最初编码为UTF-8(这是XML文档的默认编码)。在但是,当您为} 的文档
template2.docx
复制它时,您正在将编码更改为CP-1252。根据^{您指出调用
locale.getpreferredencoding(False)
会给您cp1252
,这是正在编写的编码word/document.xml
。在由于您没有显式地将
<?xml version="1.0" encoding="cp1252"?>
添加到word/document.xml
的开头,Word(或任何其他XML读取器)将其读作UTF-8,而不是CP-1252,这就是导致非法XML字符错误的原因。在因此,当使用
^{pr2}$encoding
参数对open()
进行写入时,您希望将编码指定为UTF-8:相关问题 更多 >
编程相关推荐