人间烟火,山河远阔。 无一是你,无一不是你。

在工作生活中对word使用的比较多,需要重复的操作可以使用python完成,但是最主要的还是为了自动生成漏洞页面报告,所以使用python操作word进行自动生成还是很有必要学习相关的api的。

安装

pip install python-docx

简单创建文件和写入

# coding:utf-8
from docx import Document
# 传入实例化对象,好比from flask import Flask

document = Document()
# 把对象实例化,好比app=Flask()
document.add_paragraph('你好啊世界'.decode('utf-8'),'Title')
# 写入内容,中文的话需要进行utf-8编码
# 或者用unicode编码写入
document.add_paragraph('hellw,word','Subtitle')
document.add_paragraph(u'我是正文')
document.add_paragraph(u'我也是正文')
document.add_paragraph(u'难道我就不是了吗','Body Text')
document.add_paragraph(u'你说呢','Normal')

# add_paragraph 方法的第一个参数是段落的文字,第二个可选参数就是段落的样式。
# 通过这个样式参数即可设置所添加段落的样式。如果不指定这个参数,则默认样式为『正文』
# 比如 document.add_paragraph('我是标题'.decode('utf-8'),'title')
# Title一级标题,Subtitle 二级标题,Heading n:n级标题,Normal:正文,Body Text 2正文
# 注意首字母一定要大写
document.save('demo.docx')
# 注意,如果一个文正已经被系统打开后是无法再进行写入的

显示效果如下

插入标题

document.add_paragraph('基本信息',style='Heading 1')
# 插入一级标题
document.add_paragraph('基本信息',style='Heading 2')
# 插入二级标题

表格的创建与使用

表格的创建使用api同样来源Dowument的基类

# coding:utf-8
from docx import Document

document = Document()
tables = document.add_table(rows=2, cols=6, style = 'Table Grid')
# 创建表格,rows是行数,cols是列数

tables.cell(0,1).text = (u'土拨鼠')
# 第0行的第1列(就是第一行的第二列,计算机0开始计数)
# 的内容是 土拨鼠
tables.cell(1,1).text=(u'啊啊啊啊啊')
# 第1行的第1列(就是第二行的第二列)
# 的内容是啊啊啊啊啊
document.save('test2.docx')

效果如下

Cell对象最常用,另外还要两个对象Row和Column,它们在遍历表格的时候很有用。

Table对象有两个属性rows和columns,这两个对象的返回值实际上是对象Rows和Columns,但是,Rows和Columns这两个对象,可以等同于Row的列表以及Column的列表。因此迭代、求长度等对list的操作同样适用于Rows和Columns。如果想遍历所有Cell,可以先遍历所有行(table.rows),再遍历每一行所有的Cell; 也可以先遍历所有列(table.columns),再遍历每一列所有的Cell。

调整表格长宽度

使用cell对象进行调节长宽度

from docx import Document
from docx.shared import Inches
document = Document()
row = 1 # 设置长度度1
t = document.add_table(rows=1,cols=1,style = 'Table Grid')
t.autofit = False #很重要!
w = float(row) / 2.0 # 宽度对半
t.columns[0].width = Inches(w)

添加分页

document.add_page_break()

样式的设置

常见样式就三种:

  1. 段落样式
  2. 字符样式
  3. 表格样式

自定义段落样式

# 创建自定义段落样式(第一个参数为样式名, 第二个参数为样式类型, 1为段落样式, 2为字符样式, 3为表格样式)
UserStyle1 = document.styles.add_style('UserStyle1', 1)
# 设置字体尺寸
UserStyle1.font.size = Pt(40)
# 设置字体颜色
UserStyle1.font.color.rgb = RGBColor(0xff, 0xde, 0x00)
# 居中文本
UserStyle1.paragraph_format.alignment = WD_ALIGN_PARAGRAPH.CENTER
# 设置中文字体
UserStyle1.font.name = '微软雅黑'
UserStyle1._element.rPr.rFonts.set(qn('w:eastAsia'), '微软雅黑')

定义好段落样式后,就可以直接调用了

document.dd_paragraph('好看吗','UserStyle1')

这里还有另一种方式选择颜色,字体:

document = Document()

UserStyle1 = document.styles.add_style('UserStyle1', 1)
# 设置字体尺寸
UserStyle1.font.size = Pt(9)
# 设置字体颜色
UserStyle1.font.color.rgb = RGBColor(10,105,105)
#UserStyle1.font.color.rgb = RGBColor(0xff, 0xde, 0x00)
# 居中文本
UserStyle1.font.name = '仿宋'
UserStyle1._element.rPr.rFonts.set(qn('w:eastAsia'), '仿宋')

附上rgb对照表RGB

插入图片

本地通目录下保存a.jpg,尺寸设置5号

from docx import Document
from docx.shared import Inches
document = Document()
 document.add_picture('a.jpg', width=Inches(5))

插入有序列表

document.add_paragraph('把冰箱门打开', style='List Number')
document.add_paragraph('把大象装进去', style='List Number')
document.add_paragraph('把冰箱门关上', style='List Number')

插入无序列表

document.add_paragraph('天地匆匆 惊鸿而过 路有千百个', style='List Bullet')
document.add_paragraph('遑遑无归 闲云逸鹤 人间红尘过', style='List Bullet')
document.add_paragraph('引势而流 鸿门乱局 各有各选择', style='List Bullet')
document.add_paragraph('乾震坎艮 坤巽离兑 定一切生克', style='List Bullet')

插入分页

document.add_page_break()

添加页眉页脚

# -*- coding:utf-8 -*-
#__author__:langzi
#__blog__:www.sxadmin.github.io
import os

from docx import Document
document = Document(docx=os.path.join(os.getcwd(),'default.docx'))

section = document.sections[0]
header = section.header
paragraph = header.paragraphs[0]
paragraph.text = "Report Power By Langzi"

document.add_paragraph('正文')
document.add_paragraph('我也是正文啊啊啊')

document.save('页脚.docx')

打包

用pyinstaller工具把使用到python-docx库的脚本打包成exe可执行文件后,双击运行生成的exe文件,报错:

docx.opc.exceptions.PackageNotFoundError: Package not found at 'C:\Users\ADMINI~1.PC-\AppData\Local\Temp\_MEI49~1\docx\templates\default.docx'

经过在stackoverflow上搜索,发现有人遇到过类似的问题(问题链接:cx_freeze and docx - problems when freezing),经过尝试,该问题的第二个回答可以解决这个问题:

I had the same problem and managed to get around it by doing the following. First, I located the default.docx file in the site-packages. Then, I copied it in the same directory as my .py file. I also start the .docx file with Document() which has a docx=... flag, to which I assigned the value: os.path.join(os.getcwd(), 'default.docx') and now it looks like doc = Document(docx=os.path.join(os.getcwd(), 'default.docx')). The final step was to include the file in the freezing process. Et voilà! So far I have no problem.

大概的解决步骤是这样的:

找到python-docx包安装路径下的一个名为default.docx的文件,我是通过everything这个强大的搜索工具全局搜索找到这个文件的,它在我本地所在的路径是:

E:\code\env\.env\Lib\site-packages\docx\templates

把找到的default.docx文件复制到我的py脚本文件所在的目录下。
修改脚本中创建Document对象的方式:
从原来的创建方式:

document = Document()

修改为:

import os
document = Document(docx=os.path.join(os.getcwd(), 'default.docx'))

再次用pyinstaller工具打包脚本为exe文件
把default.docx文件复制到与生成的exe文件相同的路径下,再次运行exe文件,顺利运行通过,没有再出现之前的报错,问题得到解决。

打包带页眉页脚的

如果添加页眉的化,打包exe会报错的,原因是读取配置文件xml不到

因为python-docx页眉页脚会读取安装包内的default-header.xml文件,路径在:

C:\python3\Lib\site-packages\docx\templates

尝试找源代码,找到后想通过修改源码中个获取xml的值来实现,但是发现牵一发动全身,换个思维从pyinstaller出发,修改pyinstaller的打包配置文件可以实现

import sys
from os import path
site_packages = next(p for p in sys.path if 'site-packages' in p)
print(site_packages)
 ##原来的代码是找的库'C:\\Users\\sufor\\AppData\\Roaming\\Python\\Python37\\site-packages'这个库中没有docx
#site_packages  = 'C:\Users\sufor\AppData\Local\Programs\Python\Python37\Lib\site-packages'
block_cipher = None


a = Analysis(['main.py'],
             pathex=[os.getcwd()],
             binaries=[],
             datas=[(path.join(site_packages,"docx","templates"),
"docx/templates")],    #原来datas替换为现在datas
             hiddenimports=[],
             hookspath=[],
             runtime_hooks=[],
             excludes=[],
             win_no_prefer_redirects=False,
             win_private_assemblies=False,
             cipher=block_cipher,
             noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
             cipher=block_cipher)
exe = EXE(pyz,
          a.scripts,
          a.binaries,
          a.zipfiles,
          a.datas,
          [],
          name='aaaa',
          debug=False,
          bootloader_ignore_signals=False,
          strip=False,
          upx=True,
          runtime_tmpdir=None,
          console=True , icon='logo.ico')
coll = COLLECT(exe,
               a.binaries,
               a.zipfiles,
               a.datas,
               strip=False,
               upx=True,
               name='main')

要打包的文件保存为main.py,然后目录下运行pyinstaller xxx.spec即可

参考链接

参考链接

参考链接

参考链接

参考链接