【发布时间】:2016-10-31 22:11:29
【问题描述】:
在过去的几天里,我一直在尝试创建一个脚本,该脚本将 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。
为了检查脚本是否按预期工作,我首先创建了一个测试文档(“test.docx”)并运行createNewDocx("test.docx",getXml("test.docx"),"test2.docx")。如果一切都按预期工作,这应该创建一个相同的 test.docx 副本,另存为 test2.docx。确实如此。
然后我使测试文档更加详细,并尝试修改它。而且脚本仍然有效!
然后我自信地将我的脚本应用到我真正有兴趣修改的 Word 文档:template.docx。我运行createNewDocx("template.docx",getXml("template.docx"),"template2.docx"),期望脚本会生成一个相同的template.docx 副本,但命名为template2.docx。不幸的是,新的 Word 文档无法打开;显然 XML 中有一个非法字符。
我真的不明白为什么我的代码适用于我的测试文档而不适用于我的实际文档。我会发布 template.docx 的 XML,但它包含个人信息。 test.docx 和 template.docx 之间的一个重要区别是 template.docx 是用法语编写的,因此包含重音等特殊字符,而且撇号看起来也不同。我不知道这是否是造成我麻烦的原因,但我没有其他想法。
【问题讨论】:
-
打开 template2.docx 时遇到的实际错误是什么?
-
非法 xml 字符。位置:部分:/word/document.xml,行:3,列:921
-
你能在
word/document.xml和template.docx和template2.docx中加入第3 行吗? -
我仍然怀疑这是一个编码问题。
import locale; print(locale.getpreferredencoding(False))带给你什么? -
@cpburnz 运行您建议的代码会得到 cp1252。如何找到 word/document.xml 的第三行?如果我将
getXml("template.docx")复制/粘贴到文本文件中,该文件的第三行是否与xml 文件的第三行相同?
标签: python xml character-encoding docx