如何将方程式从docx复制到另一个docx中的特定位置?

时间:2017-09-07 18:15:22

标签: python python-2.7 docx python-docx

您好我正在尝试编写一个结合了docx文件的代码。这些文件可能包含文本,图像,表格或方程式。该代码旨在复制这些对象并将它们附加到基础docx。我可以使用docx模块的'add_picture'和'add_paragraph'方法复制和合并文本,图像和表格,但我不能对单词方程式这样做。我决定尝试深入研究docx的xml并从那里复制方程部分。我可以将方程附加到我的基础文档,但是当我继续附加图片,文本和表格时,这些方程式显示在docx的 end 。我的问题是:为什么如果我按照我希望它们出现的顺序遍历附加对象并且有一种方法来阻止代码放置docx末尾的方程式。

以下是代码概述:

  1. 创建基础文档:

    文档=文档( 'basedoc.docx')

  2. 获取要附加的子文档列表
  3. 通过子文档列表开始循环
  4. 对于每个子文档,我迭代并找到不同的父对象和子对象。我在这个名为'iter_block_items'的网站上发现了这个功能(https://github.com/python-openxml/python-docx/issues/276) 文档项称为块。
  5. 对于子博士的每个块项目,我会对类型,样式以及是否存在等式进行分类:

    if isinstance(block,Paragraph):

    if "r:embed" in block._element.xml:
    
        append content,style, and equation arrays, content being a drawing/image
    
    elif "m:oMathPara" in block._element.xml:
    
        append content,style, and equation arrays, content being an equation
        equationXml.append(block._element.xml)
    
    elif 'w:br w:type="page"' in block._element.xml:
    
        append content,style, and equation arrays, content being a page break
    
    else:
    
        append content,style, and equation arrays), content being text
    

    否则:

    append content,style, and equation arrays, content being a table
    
  6. 一旦我拥有了我的内容和样式数组,我就会遍历内容数组并附加表格,图纸,分页符和文本。

        if equationXml[i]=='0': #the content is either an image, table, text, or page break
            if "Table" in str(contentStyle[i]):
                    insert table and caption
            else:
                if "drawing" in content[i]:
                    insert image and caption
    
                elif "pageBreak" in content[i]:
                    document.add_page_break()
                else:
                    insert text
        else:                        #there is an equation present
          document=EquationInsert.(document,equationXml[i])
    
  7. 我的EquationInsert文件有一个名为'AddEquation'的函数,我基本上重写了我的文档对象(其中UpdateableZipFile是我在网上找到的一个快速更新zip文件中的文件的代码):

    def AddEquation(self,document,equationContent):
        document.save('temp.docx')
        z = zipfile.ZipFile('temp.docx')
        tree=etree.parse(z.open('word/document.xml'))
        nmspcDict = tree.getroot().iter().next().nsmap
    
        for key in nmspcDict:
            ET.register_namespace(key, nmspcDict[key])
        tree2=etree.ElementTree(etree.fromstring(equationContent))
        xmlRoot2=tree2.getroot()
        xmlRoot=tree.getroot()
        xmlRoot[1].append(xmlRoot2) #note that [1] had to be used bc [0] was a comment. need to see if general case or not
    
    
        tree.write("document.xml",encoding="utf-8", xml_declaration=True, standalone="yes", pretty_print=True)
    
        with UpdateableZipFile.UpdateableZipFile("temp.docx","a") as o:
            o.write("document.xml","word/document.xml")
    
        document = Document('temp.docx') 
        os.remove('document.xml')
        z.close()
        os.remove('temp.docx')
        return document
    

    此代码添加了等式,但是当主代码继续循环遍历子文档项时,方程式只是以某种方式被推到基础文档的末尾。我已经尝试从插入方程函数返回docx并从中创建一个新文档但是没有做任何事情。如果有人有任何建议如何使方程式没有到文件的末尾,将非常感激。否则,我将不得不冒险了解如何将这些方程式转换为图像= /或docx可以处理的内容。我愿意接受解决方案/建议/评论。谢谢!

1 个答案:

答案 0 :(得分:1)

我确定您会在XML中找到答案。您可以方便地浏览XML" part"在.docx"包"使用opc-diag

Word文档中的段落和表格位于document.xml部分,作为<w:body>元素下的子元素。 <w:body>中的最后一个元素是section元素(<w:sectPr> IIRC)。如果您在该元素之后附加方程式,它们将继续浮动到底部,因为新的段落和表格被添加到上面那个sectPr元素。

我会使用尽可能短的测试文档,检查代码生成的XML,将其与您想要的方式(可能是在Word中手工创建)进行比较。这应该可以快速指出代码中存在的任何元素排序问题。