我正在尝试创建一个脚本,该脚本可以从Word文档中提取XML,对其进行修改,最后保存新的Word文档,所有这些都使用Python。这是我使用的代码,它实际上是从这里窃取的:
import zipfile
import os
import tempfile
import shutil
def getXml(docxFilename):
zip = zipfile.ZipFile(open(docxFilename,"rb"))
xmlString = str(zip.read("word/document.xml"))
return xmlString
def createNewDocx(originalDocx,xmlContent,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(xmlContent)
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)
我的代码和Virantha的代码之间的一个重要区别是,他将createNewDocx表示为一个类。 不幸的是,我不知道类是什么或它们是如何工作的,所以我认为编写一个函数会更容易。
getXML
从 Word 文档中提取 XML。我在测试文档(名为test.docx
(上尝试了一下,效果很好。理论上,createNewDocx
应该将原始docx文件(在本例中为test.docs
(和修改后的XML作为字符串来创建一个名为newFileName的新Word文档。
作为测试,我使用原始 XML 运行createNewDocx
以查看我是否会获得 text.docx
的复制版本。也就是说,我跑了
originalXml = getXml("test.docx")
createNewDocx("test.docx",originalXml,"test2.docx")
这确实创建了一个名为"test2.docx"的Word文档,但是当我尝试打开文件时,它就是无法打开;话会崩溃。
有谁知道如何修改我的代码以使其工作?
编辑:我决定包括originalXml
以防格式化方式出现问题。
b'<?xml version="1.0" encoding="UTF-8" standalone="yes"?>rn<w:document xmlns:ve="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:m="http://schemas.openxmlformats.org/officeDocument/2006/math" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml"><w:body><w:p w:rsidR="00000000" w:rsidRDefault="00971B91"><w:r><w:t>You owe me ${debt}. Pay back soon.</w:t></w:r></w:p><w:p w:rsidR="00971B91" w:rsidRPr="00971B91" w:rsidRDefault="00971B91"><w:pPr><w:rPr><w:rFonts w:ascii="Times New Roman" w:hAnsi="Times New Roman" w:cs="Times New Roman"/><w:sz w:val="24"/><w:szCs w:val="24"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="Times New Roman" w:hAnsi="Times New Roman" w:cs="Times New Roman"/><w:sz w:val="24"/><w:szCs w:val="24"/></w:rPr><w:t xml:space="preserve">You owe me </w:t></w:r><w:r><w:rPr><w:rFonts w:ascii="Times New Roman" w:hAnsi="Times New Roman" w:cs="Times New Roman"/><w:b/><w:sz w:val="24"/><w:szCs w:val="24"/></w:rPr><w:t>${debt}</w:t></w:r><w:r><w:rPr><w:rFonts w:ascii="Times New Roman" w:hAnsi="Times New Roman" w:cs="Times New Roman"/><w:sz w:val="24"/><w:szCs w:val="24"/></w:rPr><w:t xml:space="preserve">. Pay back </w:t></w:r><w:r><w:rPr><w:rFonts w:ascii="Times New Roman" w:hAnsi="Times New Roman" w:cs="Times New Roman"/><w:i/><w:sz w:val="24"/><w:szCs w:val="24"/></w:rPr><w:t>soon.</w:t></w:r></w:p><w:sectPr w:rsidR="00971B91" w:rsidRPr="00971B91"><w:pgSz w:w="12240" w:h="15840"/><w:pgMar w:top="1440" w:right="1440" w:bottom="1440" w:left="1440" w:header="708" w:footer="708" w:gutter="0"/><w:cols w:space="708"/><w:docGrid w:linePitch="360"/></w:sectPr></w:body></w:document>'
EDIT2:我更仔细地查看了上面的XML代码,意识到开头有一个不寻常的"b'",结尾有一个右括号。我删除了这些异常并再次运行代码。现在,Word 给了我一个更明智的错误,即"第 1 行,第 56 列"有问题。这对应于上面 XML 代码中的"\r\"。
所以显然我的代码没有正确提取 XML。有人知道如何解决这个问题吗?
通过强制转换"zip.read("word/document.xml"(",您将一个字节转换为字符串,以便将"b"保留为字符。
def getXml(docxFilename):
zip = zipfile.ZipFile(open(docxFilename,"rb"))
xmlString = str(zip.read("word/document.xml"))
return xmlString
所以这就是为什么"xmlString"没有属性,因为它是一个字符串。您必须删除在返回之前投射的解码:
def getXml(docxFilename):
zip = zipfile.ZipFile(open(docxFilename,"rb"))
xmlString = zip.read("word/document.xml")
return xmlString.decode('utf-8')
希望对其他人有帮助!