【问题标题】:python-docx get tables from paragraphpython-docx 从段落中获取表格
【发布时间】:2015-05-28 05:46:54
【问题描述】:

我有 .docx 文件,其中包含许多段落和表格,例如:

  1. par1
    • 表1
    • 表2
    • 表3
  2. par2

    • 表1
    • 表2

    2.1 标准 21

    • 表1
    • 表2

我需要迭代所有对象并制作字典,可能是 json 格式,例如:

 {par1: [table1, table2, table3], par2[table1,table2, {par21: [table1,table2]} ] }
从 docx.api 导入文档 文件名 = 'test.docx' 文档=文档(docx=文件名) 对于 document.tables 中的表格: 打印表 对于 document.paragraphs 中的段落: 打印段落.文本

如何关联每个段落和表格?

你有什么建议吗?

【问题讨论】:

    标签: python document docx paragraphs


    【解决方案1】:
    from docx import Document
    from docx.document import Document as _Document
    from docx.oxml.text.paragraph import CT_P
    from docx.oxml.table import CT_Tbl
    from docx.table import _Cell, Table
    from docx.text.paragraph import Paragraph
    def iter_block_items(parent):
    """
    Generate a reference to each paragraph and table child within *parent*,
    in document order. Each returned value is an instance of either Table or
    Paragraph. *parent* would most commonly be a reference to a main
    Document object, but also works for a _Cell object, which itself can
    contain paragraphs and tables.
    """
    if isinstance(parent, _Document):
        parent_elm = parent.element.body
    elif isinstance(parent, _Cell):
        parent_elm = parent._tc
    elif isinstance(parent, _Row):
        parent_elm = parent._tr
    else:
        raise ValueError("something's not right")
    for child in parent_elm.iterchildren():
        if isinstance(child, CT_P):
            yield Paragraph(child, parent)
        elif isinstance(child, CT_Tbl):
            yield Table(child, parent)
    document = Document('test.docx')
    for block in iter_block_items(document):
    
    #print(block.text if isinstance(block, Paragraph) else '<table>')
    if isinstance(block, Paragraph):
        print(block.text)
    elif isinstance(block, Table):
        for row in block.rows:
            row_data = []
            for cell in row.cells:
                for paragraph in cell.paragraphs:
                    row_data.append(paragraph.text)
            print("\t".join(row_data))
    

    【讨论】:

    • 我试过了,不是所有的文本都显示出来,只有列名出现,这是它应该呈现的吗?这是 docx 在我的系统上没有正确打开吗?我想了解有关此代码的更多信息以及如何解决我的问题。
    • 请问您是否可以重构此函数并找到 InlineShapes ?
    • 我想在这个问题上将未来的读者引向这个github,因为这是 API 的一个请求功能
    • @ImaneE。可能为时已晚,但您的问题可能与this change 有关
    • 您遗漏了 _Row。应该是 from docx.table import _Cell, Table, _Row
    【解决方案2】:

    不确定我是否在帮助,但这是我的做法

    def printTables(doc):
        for table in doc.tables:
            for row in table.rows:
                for cell in row.cells:
                    for paragraph in cell.paragraphs:
                        print(paragraph.text)
                    printTables(cell)
    

    【讨论】:

    • 不幸的是它会打印表头。
    • 建议:您可以尝试将段落文本打印到列表中并删除最有可能成为表头的第一个元素?如果您可以启动并运行它,请分享!
    【解决方案3】:

    在 python-docx 库上还没有实现这样的方法,但是有一种解决方法可以按照它们出现的顺序遍历 docx 的所有元素:https://github.com/python-openxml/python-docx/issues/40

    您可以尝试遍历所有这些并检查对象是否是表格或段落的实例,并以此为基础。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-20
      • 2016-10-02
      • 1970-01-01
      • 2015-03-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多