python操作word——python-docx和python-docx-template模块

前言:项目用到了导出文档,综合考虑使用python-docx模块

目录

  • python-docx
    • 安装
    • docx文档布局词汇
      • 三个部分
        • 文档
        • 段落
        • 文字块
      • 四级结构(表格)
    • 使用
      • 导入word
      • 读操作
        • 获取段落
        • 获取段落文本内容
        • 获取文字块文本内容
        • 遍历表格
        • 表格设置字体样式
      • 写操作
        • 保存文件
        • 添加标题
        • 添加段落
        • 添加文字块
        • 添加空白页
        • 添加图片
        • 设置样式
      • word转pdf,html
        • word---->html
        • word---->pdf
    • 实例
    • 实际案例
      • 按顺序读取word文档中的所有信息(文本,图片,表格)
      • 写入表格并增加边框
      • 最后是用到的包
  • python-docx-template
    • 安装
    • 模板语法
    • 插入图片
    • 操作表格
  • 合并word文档docxcompose
    • 安装
    • 使用
  • 字体文件ttf
    • linux中存放位置
    • windows中存放位置

python-docx

安装

pip install python-docx

docx文档布局词汇

在这里插入图片描述

三个部分

文档Document 段落Paragraph 文字块Run

文档

就是docx文档

段落

就是寻常段落

文字块

如下,短句子中有多种不同的样式,则会被划分成多个文字块。
如果所示,这个paragraph一共四个run。
在这里插入图片描述

四级结构(表格)

Document - Table - Row/Column - Cell四级结构
在这里插入图片描述

使用

导入word

from docx import Document
# 只要不指定路径,就默认为创建新Word文件
wordfile = Document(path)

读操作

获取段落

三个部分:一个doc由多个paragraph组成

paragraphs = wordfile.paragraphs 
# 得到一个段落对象列表
# [ p1,p2,p3...]
print(paragraphs)

获取段落文本内容

for paragraph in wordfile.paragraphs: print(paragraph.text)

获取文字块文本内容

一个paragraph段落由一个或者多个run文字块组成

for paragraph in wordfile.paragraphs: for run in paragraph.runs: print(run.text)

遍历表格

# 按行遍历
for table in wordfile.tables:for row in table.rows:for cell in row.cells:print(cell.text)# 按列遍历     
for table in wordfile.tables:for column in table.columns:for cell in column.cells:print(cell.text)

表格设置字体样式

表格中文字样式修改,与在段落中的样式修改一样,只是在添加文本时调用的方法不同。run=table.cell(row,col).paragraphs[0].add_run(str) #添加文本的方法run.font.name = u'宋体'run._element.rPr.rFonts.set(qn('w:eastAsia'), u'宋体')run.font.bold=True

写操作

保存文件

wordfile.save(...)
... 放需要保存的路径

添加标题

wordfile.add_heading(, level=)

在这里插入图片描述

添加段落

wordfile.add_paragraph(...)
--------------------------------------------------
wordfile = Document() 
wordfile.add_heading('一级标题', level=1) 
wordfile.add_paragraph('新的段落')

添加文字块

wordfile.add_run(...)

在这里插入图片描述

添加空白页

wordfile.add_page_break(...)

在这里插入图片描述

添加图片

wordfile.add_picture(..., width=, height=)

在这里插入图片描述

设置样式

  1. 字体设置
    在这里插入图片描述

  2. 文字其他样式设置

    from docx import Document
    from docx.shared import RGBColor, Ptwordfile = Document(file)
    for paragraph in wordfile.paragraphs:for run in paragraph.runs:run.font.bold = True  # 加粗 run.font.italic = True # 斜体 run.font.underline = True # 下划线 run.font.strike = True # 删除线 run.font.shadow = True # 阴影 run.font.size = Pt(20) # 字号 run.font.color.rgb = RGBColor(255, 0, 0) # 字体颜色
    
  3. 段落样式设置
    默认左对齐
    在这里插入图片描述

word转pdf,html

word---->html

pip install pydocx

from pydocx import PyDocX// 传入docx文件路径 或 文件content
html = PyDocX.to_html("./test.docx")// 返回html:string
f = open("test.html", 'w', encoding="utf-8")
f.write(html)
f.close()

word---->pdf

pip install pdfkit

依赖软件:
https://wkhtmltopdf.org/downloads.html

# 将wkhtmltopdf.exe程序绝对路径
path_wkthmltopdf = r'E:\wkhtmltopdf\bin\wkhtmltopdf.exe'
config = pdfkit.configuration(wkhtmltopdf=path_wkthmltopdf)
# 生成pdf文件,to_file为文件路径
pdfkit.from_file(html, to_file, configuration=config)

实例

输入文件:
在这里插入图片描述
输出文件:
在这里插入图片描述
demo代码:

from docx import Documentdoc = Document("./templates.docx")
# 查看所有属性
# 'add_heading', 'add_page_break', 'add_paragraph', 'add_picture','add_section', 'add_table',
# 'core_properties', 'element', 'inline_shapes', 'paragraphs', 'part', 'save', 'sections', 'settings', 'styles',
# 'tables'
# print(dir(doc))ps = doc.paragraphs
# print(ps)
for p in ps:text = p.textif "分析人" in text:p.text = text + "General_zy"elif "分析效果" in text:p.text = text + "高危漏洞"tables = doc.tables
# 获取模板docx中的唯一一个表
table = tables[0]for i in range(1, 3):for j in range(3):table.cell(i, j).text = str(i) + str(j)p3 = doc.add_paragraph("三.")
# 'add_run', 'alignment', 'clear', 'insert_paragraph_before', 'paragraph_format', 'part', 'runs', 'style', 'text'
p4 = doc.add_paragraph("分析团队:")
p4.add_run("dddd")doc.save("./xxx.docx")

实际案例

  1. python-docx库给我的直观感受就是难!难!难!
  2. 一大堆的私有属性,连pycharm都没有属性方法提示
  3. 连chatgpt都频繁写出错误代码
  4. 以下是我的一些总结,希望可以帮到你们

按顺序读取word文档中的所有信息(文本,图片,表格)

  1. 鬼知道CT_P,CT_Tbl是什么意思
  2. 鬼知道还有这么一些神奇的xpath//a:blip/@r:embed
  3. 磕磕巴巴的一个函数写了4天,完成了。
def read_from_word(self, src_filepath: str):"""读取输入的word附件文件"""fp = Document(src_filepath)# 遍历整个文档的所有元素(段落和表格),并记录它们在文档中出现的顺序elements = []for block in fp.element.body:if block.__class__.__name__ == 'CT_P':elements.append(('paragraph', block))elif block.__class__.__name__ == 'CT_Tbl':elements.append(('table', block))# 根据元素出现的顺序构建读取出的内容content = []for index, type_el in enumerate(elements):el_type, el = type_el[0], type_el[-1]if el_type == 'paragraph':paragraph = Paragraph(parse_xml(el.xml), parent=None)img = paragraph._element.xpath('.//pic:pic')if not img:txt = paragraph.text.strip()if txt != "":content.append(txt)else:picture = img[0]embed = picture.xpath('.//a:blip/@r:embed')[0]related_part = fp.part.related_parts[embed]image = related_part.image# 图片下载下来然后把文件位置保存到content记录顺序filepath = os.path.join(self.tmp_folder, str(index) + ".png")with open(filepath, "wb") as f:f.write(image.blob)content.append(filepath)# table将存于一个二维列表中elif el_type == 'table':table = Table(el, parent=None)tables = []for row in table.rows:row_content = []for cell in row.cells:for p in cell.paragraphs:row_content.append(p.text.strip())tables.append(row_content)content.append(tables)

写入表格并增加边框

  1. 写入表格样式需要自己设置
  2. 边框也成了一个难点
def add_other_text(self, word, text: str):# 设置附件字体if not text.isascii():p = add_text_with_style(word, text, False, u"仿宋_GB2312", 14)p.paragraph_format.line_spacing_rule = WD_LINE_SPACING.SINGLEelse:p = add_text_with_style(word, text, False, u"Times New Roman", 14)p.paragraph_format.line_spacing_rule = WD_LINE_SPACING.SINGLEdef merge_from_word(self, doc, data):style = doc.styles.add_style('Table Grid', WD_STYLE_TYPE.TABLE)style.paragraph_format.alignment = WD_TABLE_ALIGNMENT.CENTER  # 居中对齐style.font.name = '仿宋_GB2312'style.font.size = Pt(16)style._element.rPr.rFonts.set(qn('w:eastAsia'), '仿宋_GB2312')  # 设置中文字体style._element.rPr.rFonts.set(qn('w:ascii'), 'Times New Roman')  # 设置英文字体for text in data:if isinstance(text, list):table = doc.add_table(len(text), len(text[0]))# 设置表格样式table.autofit = Falsetable.style = 'Table Grid'table.width = Cm(15)for index, row in enumerate(table.rows):line = text[index]for i, cell in enumerate(row.cells):cell.text = line[i]# 设置表格边框set_cell_border(cell,top={"sz": 1, "val": "single", "color": "#000000", "space": "0"},bottom={"sz": 1, "val": "single", "color": "#000000", "space": "0"},left={"sz": 1, "val": "single", "color": "#000000", "space": "0"},right={"sz": 1, "val": "single", "color": "#000000", "space": "0"},insideH={"sz": 1, "val": "single", "color": "#000000", "space": "0"},end={"sz": 1, "val": "single", "color": "#000000", "space": "0"})# 设置表头加粗header_cells = table.rows[0].cellsfor cell in header_cells:cell.paragraphs[0].runs[0].font.bold = Trueelse:if text.endswith("png"):doc.add_picture(text, height=Cm(7.31), width=Cm(14.63))os.remove(text)else:self.add_other_text(doc, text)return doc# 设置表格的边框
def set_cell_border(cell, **kwargs):"""Set cell`s borderUsage:set_cell_border(cell,top={"sz": 12, "val": "single", "color": "#FF0000", "space": "0"},bottom={"sz": 12, "color": "#00FF00", "val": "single"},left={"sz": 24, "val": "dashed", "shadow": "true"},right={"sz": 12, "val": "dashed"},)"""tc = cell._tctcPr = tc.get_or_add_tcPr()# check for tag existnace, if none found, then create onetcBorders = tcPr.first_child_found_in("w:tcBorders")if tcBorders is None:tcBorders = OxmlElement('w:tcBorders')tcPr.append(tcBorders)# list over all available tagsfor edge in ('left', 'top', 'right', 'bottom', 'insideH', 'insideV'):edge_data = kwargs.get(edge)if edge_data:tag = 'w:{}'.format(edge)# check for tag existnace, if none found, then create oneelement = tcBorders.find(qn(tag))if element is None:element = OxmlElement(tag)tcBorders.append(element)# looks like order of attributes is importantfor key in ["sz", "val", "color", "space", "shadow"]:if key in edge_data:element.set(qn('w:{}'.format(key)), str(edge_data[key]))

最后是用到的包

import os
import re
import xlrd
from docx.shared import Cm
from docx.oxml.ns import qn
from docx import Document
from docx.oxml import parse_xml
from docx.shared import Pt
from docx.table import Table
from docx.text.paragraph import Paragraph
from xlrd import xldate_as_datetime
from docx.enum.text import WD_LINE_SPACING
from docx.enum.style import WD_STYLE_TYPE
from docx.enum.table import WD_TABLE_ALIGNMENT

python-docx-template

python-docx-template 模块主要依赖两个库, python-docx用于读取,编写和创建子文档 , jinja2用于管理插入到模板docx中的标签 。 其基本思路是利用jinja2制作Word模板,并动态向模板中插入文字、图片、表格等内容。

安装

pip install docxtpl

模板语法

由于使用的jinjia2模板,所以模板语法基本如下:

## 迭代列表
{% for var in list %}{{ var }}循环逻辑{{loop.index}}表示当前是第几次循环,从1开始
{% endfor %}## 迭代字典
{% for key, value in dict.items() %}{{ key }} {{ value }}
{% endfor %}## 另一种迭代字典的方法,这种用的比较多
{% for var in dict %}{{ var.key }} #key为字典的键
{% endfor %}{% if score>=90 %} <p>优秀</p>
{% elif score>=80 %} <p>良好</p>
{% elif score>=60 %} <p>及格</p>
{% else %} </p>不及格</p>
{% endif %}{% if val.isascii() %}{{ val }}
{% else %}fuck off
{% endif %}

插入图片

  1. 准备word,写入如下模板
这是一个模板:{{ template }}这是一个Word文件这里插入一个图片:{{ myimage }}
  1. 利用python渲染
from docxtpl import InlineImage, DocxTemplate
from docx.shared import Mm
import jinja2# 打开docx文件
tpl = DocxTemplate('test.docx')# 要装入的数据信息
context = {'template': 'Hello World!','myimage': InlineImage(tpl, 'happy.jpg', width=Mm(20)),
}jinja_env = jinja2.Environment(autoescape=True)# 填充数据
tpl.render(context, jinja_env)# 保存文件操作
tpl.save('test_temp.docx')

操作表格

在这里插入图片描述

from docxtpl import DocxTemplate, RichTexttpl = DocxTemplate('templates/cellbg_tpl.docx')context = {'alerts': [{'date': '2015-03-10','desc': RichText('Very critical alert', color='FF0000', bold=True),'type': 'CRITICAL','bg': 'FF0000',},{'date': '2015-03-11','desc': RichText('Just a warning'),'type': 'WARNING','bg': 'FFDD00',},{'date': '2015-03-12','desc': RichText('Information'),'type': 'INFO','bg': '8888FF',},{'date': '2015-03-13','desc': RichText('Debug trace'),'type': 'DEBUG','bg': 'FF00FF',},],
}tpl.render(context)
tpl.save('output/cellbg.docx')

在这里插入图片描述

合并word文档docxcompose

安装

pip install docxcompose

使用

import docx
import os
from glob import globfrom docxcompose.composer import Composerbase_dir  = "C:\\Users\\KK.JustDoIT\\Downloads\\汇总\\报修单\\日常维修-报修单-2月"
save_path  = "C:\\Users\\KK.JustDoIT\\Downloads\\汇总\\报修单"def combine_all_docx(files_list):number_of_sections=len(files_list)master = docx.Document()composer = Composer(master)for i in range(0, number_of_sections):doc_temp = docx.Document((files_list[i]))composer.append(doc_temp)composer.save(os.path.join(save_path, 'merge.docx'))# 执行
path_list = glob(os.path.join(base_dir, '*.docx'))
combine_all_docx(path_list)

字体文件ttf

docx设置字体失败,那么可能是因为没有找到字体文件。

linux中存放位置

/usr/share/fonts

在这里插入图片描述
安装字体:

  1. mkdir chinese

  2. 将下载的字体拷贝到chinese目录下
    在这里插入图片描述

  3. 执行:

    1、mkfontscale
    2、mkfontdir
    3、fc-cache
    
  4. 查看:fc-list :lang=zh
    在这里插入图片描述

windows中存放位置

在这里插入图片描述
将字体文件拖入即可。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/15464.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

工具软件中的一些操作记录

工具软件中的一些操作记录 0. 目的&#xff1a;A. VisioA01.Visio图跨文件复制保持原样A02.带有公式的visio 插入到word后模糊变形&#xff0c;如何保持原样&#xff1f; B. Windows系统B01. Windows 防火墙自动吞下载文件&#xff0c;提示病毒 C. Visual StudioC01. C/C 混合编…

C++及QT5.12.6学习日记第一周(3.1-3.7)

目录 第一天3.1 星期三 第二天3.2 星期四 第三天3.3 星期五 第四天3.4 星期六 第五天3.5 星期日 第六天3.6 星期一 第七天3.7 星期二 本周总结&#xff1a; 第一天3.1 星期三 软件安装与环境配置V C常用编译器有&#xff1a;DevC、VC6.0、Visual Studio等 安装Vis…

Qt+html+JavaScript实现类似QQ聊天界面的气泡效果

这是一个简单的类似QQ聊天界面的Demo&#xff0c;用Qt实现&#xff0c;在QWebView里嵌入网页的方式实现。先看效果图&#xff1a; 无论怎样&#xff0c;我觉得自己动手写出来的东西才是自己的&#xff0c;所以源码不全&#xff0c;重点的代码我会放上来。只是模拟实现了两个…

基于Qt的聊天软件设计实现手把手教学——高仿QQUI设计(一)

文章目录 前言一、使用工具1. Qt Creator 二、项目介绍1.客户端1.1 Socket套接字 2.服务端2.1 数据库2.2 数据处理 3.效果图4.总体系统架构图 小结 前言 最近想把自己毕业设计拿出来分享&#xff0c;我是做了一个可以通过局域网聊天的一个聊天软件。UI设计方面我也是尽力往QQ方…

基于QML模拟QQ群聊窗口

据说最近要开发简单的IM工具,于是兴起,研究了下QQ聊天窗口,大概模拟了一下群聊的聊天显示界面,遂与大家分享之 画面粗糙还望海涵 图片有点大,原理基本就是使用listview来显示每一条记录,别人的记录显示在左侧,自己的聊天记录显示在右侧,但是他们公用的一个内容控件 贴下…

❤️Java实现模拟QQ(消息通信+登陆界面美化)❤️

一、登陆界面的实现 登陆界面主要使用了JFrame&#xff0c;以及相关的一些组件&#xff0c;并且在界面中加上监听 登陆界面效果图 登陆界面代码Login类 package com.lding.login;import com.lding.ui.MsgUI;import javax.swing.*; import java.awt.*; import java.io.IOExce…

QT qq登陆界面设计

使用C结合Qt设计的类似QQ的登录界面&#xff0c;以Ui以及代码结合的方式实现&#xff0c;实现了账号注册、号密对比等功能。先看看效果图&#xff1a; 登录界面&#xff1a; 注册界面&#xff1a; 一共有两个窗口&#xff0c;通过槽函数绑定按钮来显示弹窗&#xff08;注册界面…

QT学习之QQ聊天案例

1、实现功能 本程序模拟实现QQ群聊功能&#xff0c;采用UDP通信方式&#xff0c;可以设置字体&#xff0c;保存聊天记录等&#xff0c;实时显示上线离开人数以及具体人员。可视为简化版的腾讯QQ。目前只有群聊&#xff0c;未实现一对一单独聊天。 完整源代码见&#xff1a;ht…

【教学类-36-01】Midjounery生成的四张图片切片成四张小图

作品展示&#xff1a; 把一张正方形图片的四个等大小图切割成四张图片 背景需求 最近在学习ChatGPT的绘画&#xff08;midjounery AI艺术&#xff09; 我想给中班孩子找卡通动物图片&#xff08;黑白线条&#xff09;&#xff0c;打印下来&#xff0c;孩子们练习描边、涂色…

chatgpt赋能python:Python校验身份证号码真伪

Python校验身份证号码真伪 身份证号码是我们日常生活中非常重要的证件&#xff0c;但也有一些人从事非法活动&#xff0c;对身份证号码进行伪造或者篡改。为了保护公民的合法权益&#xff0c;我们需要使用技术手段来校验身份证号码真伪。而Python作为一种广泛应用于数据处理和…

【科普级别:刚出炉的ChatGPT三连问】

科普级别&#xff1a;刚出炉的ChatGPT三连问 前言【ChatGPT是什么&#xff1f;对我们的生活有什么影响&#xff1f;】【中国为什么不能使用ChatGPT&#xff1f;美国想让中国用户使用吗&#xff1f;】【通义千问、文心一言、ChatGPT你更看好哪一个&#xff1f;】 前言 有些人连C…

又一个国内类ChatGPT模型?【秘塔科技上线自研LLM大模型「对话写作猫」】

又一个国内类ChatGPT模型&#xff1f;【秘塔科技上线自研LLM大模型「对话写作猫」】 &#xff08;马上被打脸 ~ ~&#xff09; 一直期待中国有没有类ChatGPT产品可以出现。 昨天&#xff0c;2023年2月27日&#xff0c;秘塔科技上线了自研LLM大模型「对话写作猫」&#xff0c;…

小白入门区块链(通俗易懂)

区块链基础入门 什么是区块链 科技层面解释 数学&#xff0c;密码学&#xff0c;互联网&#xff0c;计算机编程官方解释 区块链是一个分布式的共享账本和数据库&#xff0c;具有去中心化&#xff0c;不可篡改&#xff0c;全程留痕&#xff0c;可以追溯&#xff0c;集体维护&am…

2023年加密行业会更难吗?欧科云链研究院“七大趋势预测”

回望2022&#xff0c;加密行业遭遇了种种不可控因素而导致的艰难险阻&#xff0c;也在变革与发展中孕育着生机与活力。 这一年&#xff0c;我们亲眼目睹了Luna暴雷&#xff0c;三箭资本、FTX这些曾经被认为“大而不倒”的机构接连倒下&#xff0c;市场信心严重受挫&#xff1b…

​别急着骂百度,来看看大模型到底怎么用

文&#xff5c;光锥智能&#xff0c;作者&#xff5c;周文斌&#xff0c;编辑&#xff5c;王一粟 GPT-4惊艳亮相后&#xff0c;压力来到百度这边。 上台后的李彦宏和百度CTO王海峰都略显紧张&#xff0c;这在多年百度相关活动中还是非常少见。李彦宏坦言&#xff0c;“文心一言…

Node.js 高级编程之 Stream(我是跟 ChatGPT 学会的)

前言 在做 SSR Stream Render 的时候遇到了 Node.js 的 Stream&#xff0c;但是对其总是一知半解。正好最近 ChatGPT 很火&#xff0c;找他学一学吧&#xff0c;没想到真的把我教会了。PS&#xff1a;文末有跟 ChatGPT 的精彩对话&#xff08;请忽略我稀烂的英语&#xff09;。…

《不想放水》

原创&#xff1a;刘教链 * * * 由刘教链和ChatGPT共同填词。原曲&#xff1a;S.H.E.《不想长大》。 为什么就是找不到放水的证据呀 为什么救助的银行都不愿退市啊 我并不希望他拥有比特币和黄金 我惊讶的是假话竟然会变成谎话 为什么美元印钞机要转的那么快 为什么通胀和失业率…

存储器介绍

文章目录 存储系统基本概念存储器的层次存储器的分类存储器的性能指标 主存储器半导体元件的原理存储芯片的基本原理寻址 DRAM和SRAMDRAM的刷新DRAM的地址复用 只读存储器ROM主存储器和CPU的连接位扩展字扩展字位同时扩展补充 双端口RAM和多模块存储器双端口RAM解决多核CPU访存…

OpenAI文档翻译——在不通的场景下如何更好的设计ChatGPT提示词

概述 OpenAI可以被广泛的应用于各种任务&#xff0c;他为各种模型提供使用简单而功能强大的API。你可以输入一些文本作为提示词&#xff0c;OpenAI则会生成对应的提示词补全&#xff0c;在使用过程中这就是会话形式以及能够记住上下文的体现。探索如何生成提示词的最好方法就是…

如何使用ChatGPT 写官方声明?

上海车展宝马Mini展台被指区别对待中外访客&#xff0c;向外国访客送冰淇淋&#xff0c;中国访客索要时则说“没有”&#xff0c;此事引发争议。 对此&#xff0c;宝马官方也发布了官方致歉声明&#xff0c;网友看到声明后&#xff0c;纷纷发布自己的看法&#xff0c;有网友还…