-
2021-01-29 00:38:48
孤荷凌寒自学python第七十九天开始写Python的第一个爬虫9
(完整学习过程屏幕记录视频地址在文末)
今天在上一天的基础上继续完成对我的第一个代码程序的书写。
到今天终于完成了对docx模块针对word文档的段落对象的操作的学习,并通过函数封装,使得可以轻松一点直接向word文档中添加一个或多个段落文本并且设置段落的格式。
一、完成了批量添加word文档段落的函数
```
def addPToDocx(f,strp,strfont='宋体',fontsize=14,fontcolor=RGBColor(0,0,0),stralign='左对齐',strlinespacingstyle='固定值',intlinespace=20,intlinespacebefore=0,intlinespaceafter=0,intfirstlineindent=100000,isShowMsg=False):
try:
lst=strp.split('\n')
for i in lst:
i.strip()
try:
stralign=stralign.lower()
strlinespacingstyle=strlinespacingstyle.upper()
strfont.decode('utf-8')
except:
pass
#---先指定样式------------------------
styles = f.styles
fls=time.time()
strr='ghlhStyle%s'%fls #自定义的样式的名称
strr=strr.replace('.','')
strr=strr+ ''.join(random.sample('zyxwvutsrqponmlkjihgfedcbaABCDEFGHIJKLMNOPQRST',5))
s=styles.add_style(strr,WD_STYLE_TYPE.PARAGRAPH)
s.font.name=strfont
s.font.size=Pt(fontsize)
s.font.color.rgb=fontcolor
s._element.rPr.rFonts.set(qn('w:eastAsia'), strfont) #除中文外其它文字
使用的字体 ,备选项
#----选择正确的行距模式------------------------
ifstrlinespacingstyle in '固定值,EXACTLY,固定行距,固定行间距':
s.paragraph_format.line_spacing_rule=WD_LINE_SPACING.EXACTLY
#段落行距样式为固定值,必须指定行距值,否则就会变成
多倍行距 模式
elifstrlinespacingstyle in '多行行距,多倍行距,多行距,MULTIPLE':
s.paragraph_format.line_spacing_rule=WD_LINE_SPACING.MULTIPLE
#多倍行距,此模式的具体行间距由文字字号大小决定,如果后面指定了行距值,此多倍行距设置会被忽略,变成固定值模式
elifstrlinespacingstyle in '单行行距,单倍行距,单行距,SINGLE':
s.paragraph_format.line_spacing_rule=WD_LINE_SPACING.SINGLE
#段落行距样式为单倍行距
模式
elifstrlinespacingstyle in '1.5行距,1.5倍行距,一行半行距,一行半倍行距,一点五行距,一点五倍行距,ONE_POINT_FIVE':
s.paragraph_format.line_spacing_rule=WD_LINE_SPACING.ONE_POINT_FIVE
#段落行距样式为
1.5倍行距
模式
elifstrlinespacingstyle in '双行行距,双倍行距,双行距,两行行距,两倍行距,两行距,二行行距,二倍行距,二行距,DOUBLE':
s.paragraph_format.line_spacing_rule=WD_LINE_SPACING.DOUBLE
#段落行距样式为
双倍行距 模式
else:
s.paragraph_format.line_spacing_rule=WD_LINE_SPACING.AT_LEAST
#段落行距样式为
最小行距 模式
s.paragraph_format.line_spacing=Pt(intlinespace) #行距值
s.paragraph_format.space_before=Pt(intlinespacebefore)
#段前距
s.paragraph_format.space_after=Pt(intlinespaceafter)
#段后距
ifintfirstlineindent==100000:
#--这个形参的默认值表示,首行自动缩进两个字符宽度
s.paragraph_format.first_line_indent=s.font.size *
2 #段落首行缩进量
else:
s.paragraph_format.first_line_indent=Pt(intfirstlineindent)
#这时直接使用设置值
#-------------------------------
p=f.add_paragraph(i)
p.style=s #--指定刚才自定义的样式
#---接下来可调整对齐方式----
ifstralign in '靠左对齐,左边对齐,左侧,left':
p.alignment=WD_ALIGN_PARAGRAPH.LEFT #水平左对齐
elifstralign in '居中对齐,中间对齐,center':
p.alignment=WD_ALIGN_PARAGRAPH.CENTER #水平居中对齐
elifstralign in '靠右对齐,右边对齐,右侧,right':
p.alignment=WD_ALIGN_PARAGRAPH.RIGHT #水平右对齐
elifstralign in '分散对齐,两边对齐,两侧对齐,两头对齐,头尾对齐,justify':
p.alignment=WD_ALIGN_PARAGRAPH.JUSTIFY #水平分散对齐
else:
p.alignment=WD_ALIGN_PARAGRAPH.DISTRIBUTE
return True
except Exception as e:
mwordErrString='尝试将来自网页的内容写入word文档正文时出错:' + str(e) + '\n此函数由【孤荷凌寒】创建,QQ578652607'
ifisShowMsg==True:
msgbox(mwordErrString)
return False
else:
pass
finally:
pass
```
二、自定义文件【_mword.py】至此的文件内容如下:
```
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import string
import time
import random
fromdocx.enum.style import WD_STYLE_TYPE #所有样式
(包括段落、文字、表格)的枚举常量集
fromdocx.enum.text import WD_ALIGN_PARAGRAPH #对齐方式
的枚举常量集,不过在vscode中显示有错,事实又能够执行
fromdocx.enum.text import WD_LINE_SPACING #行间距的单位枚举常量集(包括:单倍行距,1.5倍行距,固定
值,最小值等)
fromdocx.oxml.ns import qn
from docx import *
fromdocx.shared import Inches #设置word中相关内容的计量单位为:英寸
fromdocx.shared import Pt #设置word中相关内容的计量单位为:磅
fromdocx.shared import RGBColor #将三个数值生成色彩对象
import _mty
import _cl #常用常量模块
import _mre
mwordErrString=''
def msgbox(info,titletext='孤荷凌寒的word模块对话框QQ578652607',style=0,isShowErrMsg=False):
return_mty.msgboxGhlh(info,titletext,style,isShowErrMsg)
def newDocX(strfilenm,isShowMsg=False):
'''
创建一个新的docx并保存在指定的路径下成为指定文件名的文件
。
'''
try:
f=Document() #创建新文档
对象
f.save(strfilenm) #保存这个文件
return f #f的类型是:
except Exception as e:
mwordErrString='尝试创建一个新的word文件时出错:' + str(e) + '\n此函数由【孤荷凌寒】创建,QQ578652607'
ifisShowMsg==True:
msgbox(mwordErrString)
return None
else:
pass
finally:
pass
def addPToDocx(f,strp,strfont='宋体',fontsize=14,fontcolor=RGBColor(0,0,0),stralign='左对齐',strlinespacingstyle='固定值',intlinespace=20,intlinespacebefore=0,intlinespaceafter=0,intfirstlineindent=100000,isShowMsg=False):
try:
lst=strp.split('\n')
for i in lst:
i.strip()
try:
stralign=stralign.lower()
strlinespacingstyle=strlinespacingstyle.upper()
strfont.decode('utf-8')
except:
pass
#---先指定样式------------------------
styles = f.styles
fls=time.time()
strr='ghlhStyle%s'%fls #自定义的样式的名称
strr=strr.replace('.','')
strr=strr+ ''.join(random.sample('zyxwvutsrqponmlkjihgfedcbaABCDEFGHIJKLMNOPQRST',5))
s=styles.add_style(strr,WD_STYLE_TYPE.PARAGRAPH)
s.font.name=strfont
s.font.size=Pt(fontsize)
s.font.color.rgb=fontcolor
s._element.rPr.rFonts.set(qn('w:eastAsia'), strfont) #除中文外其它文字
使用的字体 ,备选项
#----选择正确的行距模式------------------------
ifstrlinespacingstyle in '固定值,EXACTLY,固定行距,固定行间距':
s.paragraph_format.line_spacing_rule=WD_LINE_SPACING.EXACTLY
#段落行距样式为固定值,必须指定行距值,否则就会变成
多倍行距 模式
elifstrlinespacingstyle in '多行行距,多倍行距,多行距,MULTIPLE':
s.paragraph_format.line_spacing_rule=WD_LINE_SPACING.MULTIPLE
#多倍行距,此模式的具体行间距由文字字号大小决定,如果后面指定了行距值,此多倍行距设置会被忽略,变成固定值模式
elifstrlinespacingstyle in '单行行距,单倍行距,单行距,SINGLE':
s.paragraph_format.line_spacing_rule=WD_LINE_SPACING.SINGLE
#段落行距样式为单倍行距
模式
elifstrlinespacingstyle in '1.5行距,1.5倍行距,一行半行距,一行半倍行距,一点五行距,一点五倍行距,ONE_POINT_FIVE':
s.paragraph_format.line_spacing_rule=WD_LINE_SPACING.ONE_POINT_FIVE
#段落行距样式为
1.5倍行距
模式
elifstrlinespacingstyle in '双行行距,双倍行距,双行距,两行行距,两倍行距,两行距,二行行距,二倍行距,二行距,DOUBLE':
s.paragraph_format.line_spacing_rule=WD_LINE_SPACING.DOUBLE
#段落行距样式为
双倍行距 模式
else:
s.paragraph_format.line_spacing_rule=WD_LINE_SPACING.AT_LEAST
#段落行距样式为
最小行距 模式
s.paragraph_format.line_spacing=Pt(intlinespace) #行距值
s.paragraph_format.space_before=Pt(intlinespacebefore)
#段前距
s.paragraph_format.space_after=Pt(intlinespaceafter)
#段后距
ifintfirstlineindent==100000:
#--这个形参的默认值表示,首行自动缩进两个字符宽度
s.paragraph_format.first_line_indent=s.font.size *
2 #段落首行缩进量
else:
s.paragraph_format.first_line_indent=Pt(intfirstlineindent)
#这时直接使用设置值
#-------------------------------
p=f.add_paragraph(i)
p.style=s #--指定刚才自定义的样式
#---接下来可调整对齐方式----
ifstralign in '靠左对齐,左边对齐,左侧,left':
p.alignment=WD_ALIGN_PARAGRAPH.LEFT #水平左对齐
elifstralign in '居中对齐,中间对齐,center':
p.alignment=WD_ALIGN_PARAGRAPH.CENTER #水平居中对齐
elifstralign in '靠右对齐,右边对齐,右侧,right':
p.alignment=WD_ALIGN_PARAGRAPH.RIGHT #水平右对齐
elifstralign in '分散对齐,两边对齐,两侧对齐,两头对齐,头尾对齐,justify':
p.alignment=WD_ALIGN_PARAGRAPH.JUSTIFY #水平分散对齐
else:
p.alignment=WD_ALIGN_PARAGRAPH.DISTRIBUTE
return True
except Exception as e:
mwordErrString='尝试将来自网页的内容写入word文档正文时出错:' + str(e) + '\n此函数由【孤荷凌寒】创建,QQ578652607'
ifisShowMsg==True:
msgbox(mwordErrString)
return False
else:
pass
finally:
pass
```
三、测试用文件:
importrequests
from bs4 importBeautifulSoup
import re
importdatetime
import pymongo
fromdocx.shared import RGBColor #将三个数值生成色彩对象
import _mty
import _mf
import _mbs4
import _mmongo
import _mre
import _mdb
import _mword
intc=0
def msgbox(info,titletext='孤荷凌寒的DB模块对话框QQ578652607',style=0,isShowErrMsg=False):
return_mty.msgboxGhlh(info,titletext,style,isShowErrMsg)
def myfirst(s,h):
c2=_mdb.conLocaldbGhlh(r'C:\ProgramData\SQLITE3\slone.s3db')
lstNm=['id','title','newdate','source','content','adddate']
lstType=['int','string','date','str','memo','date']
lstLong=[0,255,0,255,0,0]
lstNull=['not null','not null','not null','null','not null','null']
lstPrimary=[True,False,False,False,False,False]
lstAuto=[True,False,False,False,False,False]
c3=_mdb.conLocaldbGhlh(r'C:\ProgramData\SQLITE3\new163.accdb')
strt='news163'
a=_mdb.newTablePlusGhlh('sqlite',c2,strt,lstNm,lstType,lstLong,lstNull,lstPrimary,lstAuto)
msgbox(str(a))
cursor=c2.cursor()
b=_mdb.newTablePlusGhlh('acc',c3,strt,lstNm,lstType,lstLong,lstNull,lstPrimary,lstAuto)
cursor3=c3.cursor()
cursor.execute('select * from ' + strt + ';')
data=cursor.fetchall()
for i in data:
msgbox(str(i))
cursor3.execute('select * from ' + strt + ';')
data=cursor3.fetchall()
for i in data:
msgbox(str(i))
#return True
#-------------------------
r=requests.get(s,headers=h)
#print(r.text) #r.text得到的是页面源html代码
_mf.writeAllTextToTxtFileGhlh('1.txt',r.text)
bs=BeautifulSoup(r.text,features="lxml") #第二个参数指明了解析器,得到的是一个beautifulsoup对象
s=bs.prettify()
_mf.writeAllTextToTxtFileGhlh('2.txt',str(s))
rs=bs.select('.bigsize') #选择指定style样式表的html标签元素
for i in rs:
ele=i.find_all('a') #每个h5标签下只有一个a标签
strls=ele[0].get('href')
#msgbox(strls) #取出地址
getcontentpage(strls,h,c2,cursor,c3,cursor3,strt)
#break
#---------------------
#cursor.execute('select * from ' + strt + ';')
#data=cursor.fetchall()
#for i in data:
# msgbox(str(i))
#cursor3.execute('select * from ' + strt + ';')
#data=cursor3.fetchall()
#for i in data:
# msgbox(str(i))
def getcontentpage(strurl,h,c2,cursor,c3,cursor3,strt):
r=requests.get(strurl,headers=h)
_mf.writeAllTextToTxtFileGhlh('3.txt',r.text)
bs=BeautifulSoup(r.text,features="lxml") #第二个参数指明了解析器,得到的是一个beautifulsoup对象
s=bs.prettify()
_mf.writeAllTextToTxtFileGhlh('4.txt',str(s))
#---------------------------
#eletemp=bs.find_all("#epContentLeft") #现在eletemp是一个rs集合对象
#上一句是错误的,通过html标签对象的id值来查找应当使用的方法是:select方法
eletemp=bs.select('#epContentLeft') #list
#msgbox(str(type(eletemp)))
eletitleparent=eletemp[0] #bs.element.Tag
#msgbox(str(type(eletitleparent)))
eletitle=eletitleparent.h1
elesource=eletitleparent.div #elesource这种对象现在被称为:bs.element.Tag对象,可以被转换为列表,但不是列表
#msgbox(str(elesource))
strtitle=_mbs4.getAllTextGhlh(eletitle)
strdate=list(elesource)[0]
strdate=_mre.getDateAndTimeString(strdate)
strsource=_mbs4.getAllTextGhlh(elesource.a)
#msgbox(strtitle)
#msgbox(strsource)
#msgbox(strdate)
#取正文
elecontent=bs.select('#endText') #所有的正文内容都这个div中,elecotent是一个List?
strcontent=_mbs4.getAllTextGhlh(elecontent)
data={
u'标题':strtitle,
u'日期':strdate,
u'来源':strsource,
u'内容':strcontent,
u'添加日期':datetime.datetime.now().__format__('%Y-%m-%d%H:%M:%S')
}
#msgbox(str(data))
#写入Mongodb数据库
c=_mmongo.conMongoDbGhlh('localhost')
db=c.news163
jh=db.first
isok=_mmongo.addNewDataGhlh(jh,data)
#msgbox(isok)
#写入sqlite3和ACCESS数据库
try:
strsql="insert into " + strt + "(title,newdate,source,content,adddate) values('"
+ strtitle + "','" + strdate + "','" + strsource + "','" + strcontent + "','" + datetime.datetime.now().__format__('%Y-%m-%d%H:%M:%S') + "');"
cursor.execute(strsql)
cursor3.execute(strsql)
c2.commit()
c3.commit()
except:
msgbox('出错了')
#写入word文档
try:
global intc
intc=intc+1
strf='d' %intc
strf=strf + '.docx'
strf='I:\\MAKEAPP\\python\\Python365\\边学习边测试文件夹\\自学PYTHON部分\\0079第七十九天爬虫实战9\\docs\\' + strf
f=_mword.newDocX(strf)
_mword.addPToDocx(f,strtitle,'黑体',28,RGBColor(0,0,100),'l','1.5',0,0,20,0)
#f.add_heading(strtitle,level=2) #这是添加标题段的方式
添加
#f.add_heading(strsource,level=3)
_mword.addPToDocx(f,strcontent)
f.save(strf) #保存时必须有文件名作参数
#f.close() #没有这个命令
except:
msgbox('写word出错!')
pass
strurl='http://tech.163.com/special/techscience/'
header={
'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
'Accept-Encoding':'gzip, deflate',
'Accept-Language':'zh-CN,zh;q=0.9',
'Cache-Control':'max-age=0',
'Connection':'keep-alive',
'Cookie':'_ntes_nuid=4c64ad6c80e3504f05302ac133efb277;
_ntes_nnid=eb7c24e0daf48e922e31dc81e431fde2,1536978956105;
Province=023; City=023; NNSSPID=acab5be191004a2b81a3a6ee60f516dc;
NTES_hp_textlink1=old;
UM_distinctid=1683adcaeaf2f8-0e31bcdad8532c-3c604504-144000-1683adcaeb094d;
vjuids=-7a5afdb26.1683adccded.0.d9d34439a4e48;
vjlast=1547175776.1547175776.30;
ne_analysis_trace_id=1547175775731;
s_n_f_l_n3=7476c45eb02177f91547175775852;
vinfo_n_f_l_n3=7476c45eb02177f9.1.0.1547175775852.0.1547176062972',
'Host':'tech.163.com',
'If-Modified-Since':'Fri, 11 Jan 2019 03:01:05 GMT',
'Referer':'http://tech.163.com/',
'Upgrade-Insecure-Requests':'1',
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36
(KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'
}
header2={
'Host':'tech.163.com',
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36
(KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36'
}
myfirst(strurl,header2)
四、今天的其它收获小结:
(一)、在docx模块操作word文档时,添加自定义样式的方法:
新的自定义样式对象=word文档对象.styles.add_style('新样式命名',WD_STYLE_TYPE.PARAGRAPH)
然后将【新的自定义样式对象】赋值给段落对象的.style属性即可
word文档段落对象的.style=新的自定义样式对象
而不能在新增段落时,像使用word的内置样式那样在新增段落的第二个参数中传入这个新的样式对象的名称。
这种方法只对word的内置样式有效,自定义样式如果也这样做,将报错。
(二)、随机文本的生成方法
1.得到一个字符串中的随机字符
random.choice('字符串')
此方法将返回【字符串】中的一个随机字符。
2.得到一个字符串中的多个随机字符,返回列表
random.sample('字符串',要返回的个数)
或者:
random.sample([字符串列表], 要返回的个数)
这两个方法都将返回【要返回的个数】个来自于【字符串】中或【字符串列表】中的字符。
——————————
今天整理的学习笔记完成,最后例行说明下我的自学思路:
根据过去多年我自学各种编程语言的经历,认为只有真正体验式,解决实际问题式的学习才会有真正的效果,即让学习实际发生。在2004年的时候我开始在一个乡村小学自学电脑 并学习vb6编程语言,没有学习同伴,也没有高师在上,甚至电脑都是孤岛(乡村那时还没有网络),有的只是一本旧书,在痛苦的自学摸索中,我找到适应自己零基础的学习方法:首先是每读书的一小节就作相应的手写笔记,第二步就是上机测试每一个笔记内容是否实现,其中会发现书中讲的其实有出入或错误,第三步就是在上机测试之后,将笔记改为电子版,形成最终的修订好的正确无误的学习笔记
。
通过反复尝试错误,在那个没有分享与交流的黑暗时期我摸黑学会了VB6,尔后接触了其它语言,也曾听过付费视频课程,结果发现也许自己学历果然太低,就算是零基础的入门课程,其实也难以跟上进度,讲师的教学多数出现对初学者的实际情况并不了解的情况,况且学习者的个体也存在差异呢?当然更可怕的是收费课程的价格往往是自己难以承受的。
于是我的所有编程学习都改为了自学,继续自己的三步学习笔记法的学习之路。
当然自学的最大问题是会走那么多的弯路,没有导师直接输入式的教学来得直接,好在网络给我们带来无限搜索的机会,大家在网络上的学习日志带给我们共享交流的机会,而QQ群等交流平台、网络社区的成立,我们可以一起自学,互相批评交流,也可以获得更有效,更自主的自学成果。
于是我以人生已过半的年龄,决定继续我的编程自学之路,开始学习python,只希望与大家共同交流,一个人的独行是可怕的,只有一群人的共同前进才是有希望的。
诚挚期待您的交流分享批评指点!欢迎联系我加入从零开始的自学联盟。
这个时代互联网成为了一种基础设施的存在,于是本来在孤独学习之路上的我们变得不再孤独,因为网络就是一个新的客厅,我们时刻都可以进行沙龙活动。
非常乐意能与大家一起交流自己自学心得和发现,更希望大家能够对我学习过程中的错误给予指点——是的,这样我就能有许多免费的高师了——这也是分享时代,社区时代带来的好福利,我相信大家会的,是吧!
根据完全共享的精神,开源互助的理念,我的个人自学录制过程是全部按4K高清视频录制的,从手写笔记到验证手写笔记的上机操作过程全程录制,但因为4K高清文件太大均超过5G以上,所以无法上传至网络,如有需要可联系我QQ578652607对传,乐意分享。上传分享到百度网盘的只是压缩后的720P的视频。
我的学习过程录像百度盘地址分享如下:(清晰度:1280x720)
提取码:lg9r
Bilibili:
喜马拉雅语音笔记:
更多相关内容 -
python+PyDocX+BeautifulSoup+PyQt5实现word转html的可视化插件
2022-07-11 15:22:59python+PyDocX+BeautifulSoup+PyQt5实现word转html的可视化插件 -
〖Python自动化办公篇⑪〗- word文件自动化 - word 转 PDF(pdfkit与pydocx相结合)
2022-05-16 21:54:49'html_string_test.pdf') 运行结果如下: 结合 pydocx 将 word 转 html 再转 pdf 首先需要安装 pydocx 依赖包 —> pip install pydocx 导入 PyDocX 函数 —> from pydocx import PyDocX 利用 PyDocX 将 word 文件...万叶集 🎉 隐约雷鸣,阴霾天空。 🎉 🎉 但盼风雨来,能留你在此。 🎉
前言:
✌ 作者简介:渴望力量的哈士奇 ✌,大家可以叫我 🐶哈士奇🐶 ,一位致力于 TFS - 全栈 赋能的博主 ✌
🏆 CSDN博客专家认证、新星计划第三季全栈赛道 top_1 、华为云享专家、阿里云专家博主 🏆
📫 如果文章知识点有错误的地方,请指正!和大家一起学习,一起进步👀
💬 人生格言:优于别人,并不高贵,真正的高贵应该是优于过去的自己。💬
🔥 如果感觉博主的文章还不错的话,还请👍关注、点赞、收藏三连支持👍一下博主哦
专栏系列(点击解锁) 学习路线指引 知识定位 🔥Python全栈白皮书🔥 零基础入门篇 以浅显易懂的方式轻松入门,让你彻底爱上Python的魅力。 语法进阶篇 主要围绕多线程编程、正则表达式学习、含贴近实战的项目练习 。 自动化办公篇 实现日常办公软件的自动化操作,节省时间、提高办公效率。 自动化测试实战篇 从实战的角度出发,先人一步,快速转型测试开发工程师。 数据库开发实战篇 更新中 爬虫入门与实战 更新中 数据分析篇 更新中 前端入门+flask 全栈篇 更新中 django+vue全栈篇 更新中 拓展-人工智能入门 更新中 网络安全之路 踩坑篇 记录学习及演练过程中遇到的坑,便于后来居上者 网安知识扫盲篇 三天打鱼,不深入了解原理,只会让你成为脚本小子。 vulhub靶场漏洞复现 让漏洞复现变得简单,让安全研究者更加专注于漏洞原理本身。 shell编程篇 不涉及linux基础,最终案例会偏向于安全加固方向。 [待完结] WEB漏洞攻防篇 2021年9月3日停止更新,转战先知社区等安全社区及小密圈 渗透工具使用集锦 2021年9月3日停止更新,转战先知社区等安全社区及小密圈 点点点工程师 测试神器 - Charles 软件测试数据包抓包分析神器 测试神器 - Fiddler 一文学会 fiddle ,学不会倒立吃翔,稀得! 测试神器 - Jmeter 不仅是性能测试神器,更可用于搭建轻量级接口自动化测试框架。 RobotFrameWork Python实现的自动化测试利器,该篇章仅介绍UI自动化部分。 Java实现UI自动化 文档写于2016年,Java实现的UI自动化,仍有借鉴意义。 MonkeyRunner 该工具目前的应用场景已不多,文档已删,为了排版好看才留着。
该章节我们将要学习如何将 word 文件转为 PDF文件,其实网上有很多种生成 PDF 的教程,不过绝大多数都是以
windows
为主的,并且兼容有很多的问题。windows、mac、linux
同时兼容的情况比较少,所以今天的章节我们就来学习一下如何在windows、mac、linux
三种系统中都可以生成 PDF 的解决方案。🐳 pdf 工具包 - pdfkit
pdfkit 包的安装:
pip install pdfkit
依赖工具:
https://wkhtmltopdf.org/downloads.html
下载符合与自己当前系统的安装包安装完成之后就可以达到兼容的效果了。🐬 html 转 pdf
html 转 pdf 方法:
pdfkit.from_file(html文件, 保存路径)
利用pdfkit.from_file() 函数传入 "html" 文件与 pdf 的保存路径
代码示例如下:
# coding:utf-8 import pdfkit # 需安装 pdfkit 第三方包 "pip install pdfkit" 以及第三方依赖 "wkhtmltopdf" pdfkit.from_file('html测试文件.html', 'html测试文件.pdf')
运行结果如下:
🐬 网址 转 pdf
网址 转 pdf 方法:
pdfkit.from_url(网址, 保存路径)
利用pdfkit.from_url() 函数传入 "网址" 文件与 pdf 的保存路径
“html” 文件与网址的区别在于实际上html文件有可能是我们本地开发生成的,也有可能是通过 “网页另存为” 的方式存储在本地的。所以 网址 与 html文件 还是有一点点区别的,但是它们的本质其实是一样的。
代码示例如下:
# coding:utf-8 import pdfkit # 需安装 pdfkit 第三方包 "pip install pdfkit" 以及第三方依赖 "wkhtmltopdf" pdfkit.from_url('https://www.163.com', 'test1.pdf')
运行结果如下:
🐬 字符串生成pdf
网址 转 pdf 方法:
pdfkit.from_string(基于html的字符串, 保存路径)
利用pdfkit.from_string() 函数传入 "网址" 文件与 pdf 的保存路径
基于html的字符串
其实就是前端的一种超文本文件格式,以这种前端规范生成的字符串其实就是 html 的字符串了# coding:utf-8 import pdfkit # 需安装 pdfkit 第三方包 "pip install pdfkit" 以及第三方依赖 "wkhtmltopdf" html = """ <html> <head> <meta charset="utf-8" /> </head> <body> <p>你好,这是一个html字符串转为pdf的测试文件</p> </body> </html> """ pdfkit.from_string(html, 'html_string_test.pdf')
运行结果如下:
🐳 结合 pydocx 将 word 转 html 再转 pdf
- 首先需要安装
pydocx
依赖包 —>pip install pydocx
- 导入
PyDocX
函数 —>from pydocx import PyDocX
- 利用
PyDocX
将 word 文件转换为 html 格式(会生成一个 html 的字符串对象) - 将 生成的 html 字符串 写入到一个 html 文件中
- 然后利用 pdfkit 包的
pdfkit.from_file()
函数将其转为 pdf 文件
代码示例如下:
# coding:utf-8 import pdfkit # pip install pdfkit from pydocx import PyDocX # pip install pydocx html = PyDocX.to_html('简历1.docx') f = open('简历1.html', 'w') f.write(html) f.close() #pdfkit.from_file('html1.html', 'test3.pdf') pdfkit.from_string(html, '简历1.pdf')
运行结果如下:
PS:感觉这种方法进行Word转PDF不好用啊,转成PDF之后Word格式和样式全变了,无法作为商业化方案。
- 首先需要安装
-
pydocx_texteditor_
2021-09-30 02:15:00treatment of text with pydocx -
Python库 | PyDocX-0.9.3.tar.gz
2022-03-07 10:37:39python库。 资源全名:PyDocX-0.9.3.tar.gz -
word文档转html格式在线预览,使用了phpoffice,pydocx,java POI各方案,最终用unoconv解决
2021-01-27 11:24:58然后,我就想用python来解决这个问题,查到了python有个pydocx库可以处理word文档,于是我就安装了一下。 pip install pydocx 这个库用起来也很简单,主要代码如下: from pydocx import PyDocX ...最近客户要做一个word,excel 文件在线预览功能,以下是实现此功能的全过程。
由于我们用的是PHP开发项目,最开始想到的是用PHPoffice里的phpword来进行转换,以下是关键代码。<?php $phpWord = \PhpOffice\PhpWord\IOFactory::load('test.doc'); $xmlWriter = \PhpOffice\PhpWord\IOFactory::createWriter($phpWord, "HTML"); $xmlWriter->save('test.html);
用这种方法转是可以转,但是转出来的html文件相对原文件,丢失了很多字,如果说样式和原文不一样还可以忍受,但是内容丢失,就不太好了,而且对DOC格式又无法处理,所以这种方法,我最终选择了放弃。
然后,我就想用python来解决这个问题,查到了python有个pydocx库可以处理word文档,于是我就安装了一下。pip install pydocx
这个库用起来也很简单,主要代码如下:
from pydocx import PyDocX html = PyDocX.to_html("test2.doc") f = open("test.html", 'w', encoding="utf-8") f.write(html) f.close()
转换效果也还可以,除了表格样式和原文有点不一样以外,内容倒是没丢失,但是有一个问题,这个库是转换docx的,对doc转换不了,我们客户还上传挺多doc格式的文件的,于是我只好另外想办法。
查资料发现java有个poi库可以用来对word文件进行转换, Apache POI是Apache软件基金会的开放源码函式库,POI提供API给Java程序对Microsoft Office格式档案读和写的功能。我想试一下,查资料半天,就开始写了,先Maven引入依赖:<dependencies> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>4.1.2</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>4.1.2</version> </dependency> <!-- 针对2003版本的库 --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-scratchpad</artifactId> <version>4.1.2</version> </dependency> <dependency> <groupId>fr.opensagres.xdocreport</groupId> <artifactId>fr.opensagres.poi.xwpf.converter.xhtml</artifactId> <version>2.0.2</version> </dependency> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.4.3</version></dependency> </dependencies>
以下是引用别人的可用代码:
import cn.hutool.core.img.ImgUtil; import fr.opensagres.poi.xwpf.converter.xhtml.Base64EmbedImgManager; import fr.opensagres.poi.xwpf.converter.xhtml.XHTMLConverter; import fr.opensagres.poi.xwpf.converter.xhtml.XHTMLOptions; import org.apache.poi.hwpf.HWPFDocument; import org.apache.poi.hwpf.converter.WordToHtmlConverter; import org.apache.poi.openxml4j.util.ZipSecureFile; import org.apache.poi.xwpf.usermodel.XWPFDocument; import org.w3c.dom.Document; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import java.awt.image.BufferedImage; import java.io.*; /** * office转换工具测试 * */ public class OfficeConvertUtil { /** * 将word2003转换为html文件 2017-2-27 * * @param wordPath word文件路径 * @param wordName word文件名称无后缀 * @param suffix word文件后缀 * @throws IOException * @throws TransformerException * @throws ParserConfigurationException */ public static String Word2003ToHtml(String wordPath, String wordName, String suffix) throws IOException, TransformerException, ParserConfigurationException { String htmlPath = wordPath + File.separator + "html" + File.separator; String htmlName = wordName + ".html"; final String imagePath = htmlPath + "image" + File.separator; // 判断html文件是否存在,每次重新生成 File htmlFile = new File(htmlPath + htmlName); // if (htmlFile.exists()) { // return htmlFile.getAbsolutePath(); // } // 原word文档 final String file = wordPath + File.separator + wordName + suffix; InputStream input = new FileInputStream(new File(file)); HWPFDocument wordDocument = new HWPFDocument(input); WordToHtmlConverter wordToHtmlConverter = new WordToHtmlConverter( DocumentBuilderFactory.newInstance().newDocumentBuilder() .newDocument()); wordToHtmlConverter.setPicturesManager((content, pictureType, suggestedName, widthInches, heightInches) -> { BufferedImage bufferedImage = ImgUtil.toImage(content); String base64Img = ImgUtil.toBase64(bufferedImage, pictureType.getExtension()); // 带图片的word,则将图片转为base64编码,保存在一个页面中 StringBuilder sb = (new StringBuilder(base64Img.length() + "data:;base64,".length()).append("data:;base64,").append(base64Img)); return sb.toString(); }); // 解析word文档 wordToHtmlConverter.processDocument(wordDocument); Document htmlDocument = wordToHtmlConverter.getDocument(); // 生成html文件上级文件夹 File folder = new File(htmlPath); if (!folder.exists()) { folder.mkdirs(); } // 生成html文件地址 OutputStream outStream = new FileOutputStream(htmlFile); DOMSource domSource = new DOMSource(htmlDocument); StreamResult streamResult = new StreamResult(outStream); TransformerFactory factory = TransformerFactory.newInstance(); Transformer serializer = factory.newTransformer(); serializer.setOutputProperty(OutputKeys.ENCODING, "utf-8"); serializer.setOutputProperty(OutputKeys.INDENT, "yes"); serializer.setOutputProperty(OutputKeys.METHOD, "html"); serializer.transform(domSource, streamResult); outStream.close(); return htmlFile.getAbsolutePath(); } /** * 2007版本word转换成html 2017-2-27 * * @param wordPath word文件路径 * @param wordName word文件名称无后缀 * @param suffix word文件后缀 * @return * @throws IOException */ public static String Word2007ToHtml(String wordPath, String wordName, String suffix) throws IOException { ZipSecureFile.setMinInflateRatio(-1.0d); String htmlPath = wordPath + File.separator + "html" + File.separator; String htmlName = wordName + ".html"; String imagePath = htmlPath + "image" + File.separator; // 判断html文件是否存在 File htmlFile = new File(htmlPath + htmlName); // if (htmlFile.exists()) { // return htmlFile.getAbsolutePath(); // } // word文件 File wordFile = new File(wordPath + File.separator + wordName + suffix); // 1) 加载word文档生成 XWPFDocument对象 InputStream in = new FileInputStream(wordFile); XWPFDocument document = new XWPFDocument(in); // 2) 解析 XHTML配置 (这里设置IURIResolver来设置图片存放的目录) File imgFolder = new File(imagePath); // 带图片的word,则将图片转为base64编码,保存在一个页面中 XHTMLOptions options = XHTMLOptions.create().indent(4).setImageManager(new Base64EmbedImgManager()); // 3) 将 XWPFDocument转换成XHTML // 生成html文件上级文件夹 File folder = new File(htmlPath); if (!folder.exists()) { folder.mkdirs(); } OutputStream out = new FileOutputStream(htmlFile); XHTMLConverter.getInstance().convert(document, out, options); return htmlFile.getAbsolutePath(); } public static void main(String[] args) throws Exception { System.out.println(Word2003ToHtml("D:\\tmp", "test", ".doc")); System.out.println(Word2007ToHtml("D:\\tmp", "test2", ".docx")); } }
用java 倒是转换doc格式转的挺好的,但是转换docx格式的时候,样式全乱了,我查了半天POI的文档,网上也没有哪位大佬来解决这个样式乱的问题,于是我想用python来转docx ,java来转doc,但是又觉得太麻烦。
在查了半天资料以后,我最终的解决办法如下。
还是回到了用php处理,但是不是用phpoffice来处理,而是用unocov进行转换,先装libreofficeyum install libreoffice
然后装unocov
yum install unoconv
用以下命令就可以转换了
unoconv -f html -o test.html test.doc
-f是输出格式,-o是输出文件 最后面是输入文件,具体用法可以查相关文档,我在php里执行外部命令,生成转换好的文件以后再重定向到生成的文件上面去,由于excel 转html报错,所以我针对excel 转成了pdf.
if (file_exists($source)) { $dir = dirname($source); $ext=pathinfo($source)['extension']; if(!in_array($ext,['xls','xlsx'])){ $filetype='html'; }else $filetype='pdf'; $filename = strstr(basename($source), '.', true) . '.'.$filetype; $file = $filename; if(!file_exists('data/' . $file)){ //echo "sudo /usr/bin/unoconv -f {$filetype} -o " . '/data/web/public/data/' . $file . ' ' . '/data/web/data_manage/public/' . $source;exit; $res= shell_exec("sudo /usr/bin/unoconv -f {$filetype} -o " . '/data/web/public/data/' . $file . ' ' . '/data/web/data_manage/public/' . $source); if(!file_exists('data/' . $file)){ dump($res); exit('生成预览文件出错'); } } header("Location:".'/data/' . $file); exit(); } else exit('文件不存在');
最后,总算是把doc,docx 还有excel文件,wps文件都能预览出来,样式还是有点变化,内容没有丢失,客户也还算是能接受,以上是我解决这个问题的心得,希望能帮到大家。
-
【Python】Django框架使用PyDocX模块,实现页面预览docx格式文件
2021-01-11 10:26:45DIR) sys = str(Path(BASE_DIR)) print(sys) file_path = request.GET.get('file_path') print(file_path) file_path = sys + '/static/upload/' + file_path print(file_path) load_html = PyDocX.to_html(file_...首先,setting对于TEMPLATES的设置
TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'static')] , 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', # 'social_django.context_processors.backends', # 'social_django.context_processors.login_redirect', ], }, }, ]
几个重要文件位置
预览上传过后的docx文档,上传很简单,不做演示,doc.html建空的html格式文件即可
def viewdoc(request): # print(BASE_DIR) sys = str(Path(BASE_DIR)) print(sys) file_path = request.GET.get('file_path') print(file_path) file_path = sys + '/static/upload/' + file_path print(file_path) load_html = PyDocX.to_html(file_path) # print(load_html) f = open("static/doc.html", 'w', encoding="utf-8") # print(f) f.write(load_html) f.close() return render(request, '../static/doc.html')
以上关于文件路径打印结果如下
-
Python读取Word(.docx)正文信息的方法
2020-12-23 15:57:10本文介绍用Python简单读取*.docx文件信息,一些python-word库就是对这种方法的扩展。 介绍分两部分: Word(*.docx)文件简述 Python提取Word信息 Word(*.docx)文件简述 大约在2008年以前,Office产品中Word用.doc... -
python操作docx写入内容,并控制文本的字体颜色
2020-09-17 23:00:54今天小编就为大家分享一篇python操作docx写入内容,并控制文本的字体颜色,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧 -
python-docx修改已存在的Word文档的表格的字体格式方法
2020-09-20 12:36:15今天小编就为大家分享一篇python-docx修改已存在的Word文档的表格的字体格式方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧 -
孤荷凌寒自学python第七十九天开始写Python的第一个爬虫9并使用pydocx模块将结果写入word文档...
2019-01-25 22:12:00孤荷凌寒自学python第七十九天开始写Python的第一个爬虫9 (完整学习过程屏幕记录视频地址在文末) 今天在上一天的基础上继续完成对我的第一个代码程序的书写。 ...到今天终于完成了对docx模块针对word文档的段落... -
python docx文档内容提取与写入(汇总)
2020-01-07 14:55:18通过python 提取docx文件中的文本内容,包括:段落、文本域、页眉页脚、目录、超链接、脚注等各处文本 import os import re import docx import lxml import shutil ...from pydocx import PyDocX f... -
Python不同数据格式的读入.docx
2020-07-09 14:06:44Python不同数据格式的读入.docx -
python docx文档转html页面
2020-12-08 18:17:22这里使用pydocx的库,安装pip3 install pydocx,可以直接对docx文件进行处理,简单粗暴,PyDocX.to_html("**.docx"),返回值就是转换后的html的源码,然后再通过写文件,写到html文件里面。 from pydocx import ... -
Python 读取各类文件格式的文本信息 | doc,excel,html,mht
2020-12-11 23:35:46这个可以有,前面说了,python拥有大量丰富的第三方库(先夸一波我大python),历经千辛万苦终于找到了,一个能转换docx文档格式的第三方库,pydocx,pydocx库中有个方法pydocx.to_html()就可以直接将docx文档转换为... -
python实现doc转docx,以及docx转html
2020-04-08 21:50:54python里面实现doc转html貌似有点麻烦,这里先把doc转为docx,然后再转为html,代码... ...from pydocx import PyDocX # docx转html用 ''' doc文件转docx文件 fullpath:路径+文件名(不带后缀) 如:D:\\test\\文件1 '... -
python doc文档转化为html文档,保留大部分原有格式、字体、字体颜色
2020-11-12 15:33:22如下doc文档的图。与转化为html的图作对比,效果还是... ...from pydocx import PyDocX html = PyDocX.to_html("防晒指南.docx") f = open("test.html", 'w', encoding="utf-8") f.write(html) f.close() ... -
python 3.7引用docx操作word文档报错exception
2018-12-05 14:11:17python 3.7引用docx操作word文档报错“docx.opc.exceptions.PackageNotFoundError: Package not found at.....”,网上搜的方法都尝试过了,没有用。python__docx-0.8.6-py2.py3-none-any.whl这个包已经没有了,下载...