• python文件处理:解析docx/word文件文字、图片、复选框


    前言

            因为一些项目原因,我需要提供解析docx内容功能。本来以为这是一件比较简单的工作,没想到在解析复选框选项上吃了亏,并且较长一段时间内通过各种渠道都没有真正解决这一问题,反而绕了远路。

            终于,我在github python-docx模块的Issues中找到了重要的思路及线索,并最终通过后续努力,实现了【解析docx/word文件文字、图片、复选框】这一功能。

    Feature: Read checkboxes in Word forms · Issue #224 · python-openxml/python-docx · GitHub

     python-docx基础操作

    1. # 安装python-docx模块
    2. pip install python-docx
    1. import os
    2. import docx
    3. import time
    4. # 图片附件的存储地址
    5. image_save_path = 'appendix_dir'
    6. # 读取docx表格里的数据,图片及文字
    7. def read_table_from_docx(file_path):
    8. """
    9. :param file_path:
    10. :return: table_data, images
    11. """
    12. # 读取docx/word文件
    13. doc = docx.Document(file_path)
    14. # 获取docx中的table对象
    15. tables = doc.tables
    16. table_data = []
    17. images = []
    18. # 拿取文件中的图片对象,并存储在images列表里
    19. for rel in doc.part.rels.values():
    20. if "image" in rel.reltype:
    21. image = rel.target_part
    22. image_data = image.blob
    23. images.append(image_data)
    24. # 读取文件表格中的文字内容
    25. # 这里不能解析特殊字符和复选框
    26. # 并且合并单元格的文字内容,将出现多行多列重复出现,需要注意
    27. for table in tables:
    28. for row in table.rows:
    29. row_data = []
    30. for cell in row.cells:
    31. # print(cell, cell.text)
    32. row_data.append(cell.text)
    33. table_data.append(row_data)
    34. return table_data, images
    35. table_data, images = read_table_from_docx('template.docx')
    36. print(table_data)
    37. # 另存docx图片到本地
    38. for i, image_data in enumerate(images):
    39. # 拼接 存储图片 绝对路径
    40. image_name = f"expert_{int(time.time() * 1000)}.jpg"
    41. with open(os.path.join(image_save_path, image_name), "wb") as f:
    42. f.write(image_data)

    拿取复选框选项 

            关于docx复选框,在这次项目中遇到了一种独特的复选框样式,这种样式并不是通过wps里的【复选框内容控件】创建的,让我一时没办法找到方向。

            这是正常用wps添加的复选框方式

            很明显,和我的目标不太一样

            二者都没办法通过【python-docx基础操作】拿到,因此我只能继续刨坑,终于如【前言】所述,我不得已去模块github的评论区里找到了线索——直接以xml的形式剖析docx文件,并获取复选框选项。

            这里为了节约文本资源(太懒了),直接上代码吧!

    1. from docx import Document
    2. document = Document('template1.docx')
    3. tables = document.tables
    4. content = []
    5. for table in tables:
    6. for row in table.rows:
    7. for cell in row.cells:
    8. for paragraph in cell.paragraphs:
    9. p = paragraph._element
    10. # 打印docx的xml内容形式
    11. # print(p.xml)
    12. # 拿取所有标签的匹配xml数据
    13. checkBoxes = p.xpath('.//w14:checkbox')
    14. if checkBoxes:
    15. # 解析内部的内容
    16. for checkBox in checkBoxes:
    17. # 尝试匹配xml中的对象,也就是上面wps自建的复选框
    18. checked_state = checkBox.xpath('.//w14:checked/@w14:val', namespaces={'w14':'http://schemas.microsoft.com/office/word/2010/wordml'})
    19. if checked_state:
    20. checked_value = checked_state[0] # 获取第一个匹配的属性值
    21. print(paragraph.text, "Checked value:", checked_value)
    22. break
    23. # 这是原模板的复选框选项拿取方案
    24. # checkBoxes = p.xpath('.//w:r')
    25. # if checkBoxes:
    26. # for checkBox in checkBoxes:
    27. # checked_state = checkBox.xpath('.//w:sym/@w:char')
    28. # if checked_state:
    29. # checked_value = checked_state[0] # 获取第一个匹配的属性值
    30. # print(paragraph.text, "Checked value:", checked_value)
    31. # break

            这是我的结果【1是选择,0是未选择】

            这是docx解析后的xml内容,请自行体会代码与它的联系吧

    1. "http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:wpc="http://schemas.microsoft.com/office/word/2010/wordprocessingCanvas" xmlns:mc="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:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:wpi="http://schemas.microsoft.com/office/word/2010/wordprocessingInk" xmlns:wne="http://schemas.microsoft.com/office/word/2006/wordml" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" xmlns:wpsCustomData="http://www.wps.cn/officeDocument/2013/wpsCustomData">
    2. "both"/>
    3. "eastAsia" w:ascii="仿宋_GB2312" w:hAnsi="仿宋_GB2312" w:eastAsia="仿宋_GB2312" w:cs="仿宋_GB2312"/>
    4. "single"/>
    5. "en-US" w:eastAsia="zh-CN"/>
    6. "default" w:ascii="仿宋_GB2312" w:hAnsi="仿宋_GB2312" w:eastAsia="仿宋_GB2312" w:cs="仿宋_GB2312"/>
    7. "21"/>
    8. "21"/>
    9. "Wingdings" w:char="00A8"/>
    10. "eastAsia" w:ascii="仿宋_GB2312" w:hAnsi="仿宋_GB2312" w:eastAsia="仿宋_GB2312" w:cs="仿宋_GB2312"/>
    11. "21"/>
    12. "21"/>
    13. "en-US" w:eastAsia="zh-CN"/>
    14. 这是选项一
    15. id="0" w:name="_GoBack"/>
    16. id="0"/>
    17. "eastAsia" w:ascii="仿宋_GB2312" w:hAnsi="仿宋_GB2312" w:eastAsia="仿宋_GB2312" w:cs="仿宋_GB2312"/>
    18. "auto"/>
    19. "2"/>
    20. "21"/>
    21. "24"/>
    22. "en-US" w:eastAsia="zh-CN" w:bidi="ar-SA"/>
    23. id w:val="147457823"/>
    24. "1"/>
    25. "2612" w14:font="MS Gothic"/>
    26. "2610" w14:font="MS Gothic"/>
    27. "eastAsia" w:ascii="仿宋_GB2312" w:hAnsi="仿宋_GB2312" w:eastAsia="仿宋_GB2312" w:cs="仿宋_GB2312"/>
    28. "auto"/>
    29. "2"/>
    30. "21"/>
    31. "24"/>
    32. "en-US" w:eastAsia="zh-CN" w:bidi="ar-SA"/>
    33. ascii="MS Gothic" w:hAnsi="MS Gothic" w:eastAsia="宋体" w:cs="Times New Roman"/>
    34. "auto"/>
    35. "2"/>
    36. "21"/>
    37. "24"/>
    38. "en-US" w:eastAsia="zh-CN" w:bidi="ar-SA"/>
    39. "eastAsia" w:ascii="仿宋_GB2312" w:hAnsi="仿宋_GB2312" w:eastAsia="仿宋_GB2312" w:cs="仿宋_GB2312"/>
    40. "0"/>
    41. "0"/>
    42. "000000"/>
    43. "0"/>
    44. "21"/>
    45. "21"/>
    46. "none"/>
    47. "single" w:color="000000" w:sz="4" w:space="0"/>
    48. "en-US" w:eastAsia="zh-CN" w:bidi="ar"/>
    49. "0" distB="0" distL="114300" distR="114300" simplePos="0" relativeHeight="251659264" behindDoc="0" locked="0" layoutInCell="1" allowOverlap="1">
    50. "0" y="0"/>
    51. "column">
    52. 0
    53. "paragraph">
    54. 0
    55. "18415" cy="19685"/>
    56. "0" t="0" r="0" b="0"/>
    57. id="1" name="图片_2"/>
    58. "http://schemas.openxmlformats.org/drawingml/2006/main">
    59. "http://schemas.openxmlformats.org/drawingml/2006/picture">
    60. "http://schemas.openxmlformats.org/drawingml/2006/picture">
    61. id="1" name="图片_2"/>
    62. "rId4"/>
    63. "0" y="0"/>
    64. "18415" cy="19685"/>
    65. "rect">
  • 相关阅读:
    css:不同设备的适配和响应
    Maven 仓库地址
    ggplot 分面的细节调整汇总
    QT中软件cpu占用率很高,甚至达到了50% 62%左右
    网络编程套接字
    力扣:165. 比较版本号(Python3)
    OpenSSL/SSL.py报错:with _from_buffer(buf) as data:
    智能配电房管理
    30.CSS文本悬停过渡效果
    第四章——密码学的数学引论
  • 原文地址:https://blog.csdn.net/G541788_/article/details/137265022