<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          最全總結(jié) | 聊聊 Python 辦公自動化之 Word(下)

          共 9113字,需瀏覽 19分鐘

           ·

          2020-11-16 18:44

          聊聊 Python 數(shù)據(jù)處理全家桶(Memca 篇)

          點擊上方“AirPython”,選擇“加為星標

          第一時間關(guān)注 Python 技術(shù)干貨!


          1. 前言

          關(guān)于 Word 文檔的讀寫,前面兩篇文章分別進行了一次全面的總結(jié)

          最全總結(jié) | 聊聊 Python 辦公自動化之 Word(上)

          最全總結(jié) | 聊聊 Python 辦公自動化之 Word(中)

          本篇文章作為一個辦公自動化 Word 篇的一個補充,寫寫幾個比較實用的辦公場景

          包含:

          • 頁眉頁腳處理

          • 合并多個文檔

          • 新增數(shù)字索引

          • doc 批量轉(zhuǎn) docx

          • 對比文檔差異性

          • 特別內(nèi)容標注

          • 替換文字內(nèi)容

          2. 頁眉頁腳

          每一個頁面章節(jié)都包含:頁眉頁腳

          它可以單獨設(shè)置,每個頁面都不一樣;也可以全部設(shè)置成與首頁一樣

          這個功能,由章節(jié)對象中的屬性?different_first_page_header_footer 來控制

          • 當值為 True 時,代表頁眉頁腳不同于首頁,每個頁面章節(jié)的頁眉、頁腳都可以單獨設(shè)置

          • 當值為 False 時,所有頁面的頁眉、頁腳都一樣

          #?1、獲取待處理頁眉、頁腳的章節(jié)
          header?=?self.doc.sections[0].header
          footer?=?self.doc.sections[0].footer

          #?True?if?this?section?displays?a?distinct?first-page?header?and?footer
          # True:頁眉頁腳不同于首頁,每個頁面章節(jié)的頁眉頁腳單獨設(shè)置
          # False:每個頁面的頁眉頁腳相同
          self.doc.sections[0].different_first_page_header_footer?=?True

          添加頁眉頁腳包含兩種,分別是:普通頁眉頁腳、自定義樣式的頁眉頁腳

          1 - 普通頁眉頁腳

          def?add_norm_header_and_footer(header,?footer,?header_content,?footer_content):
          ????"""
          ????增加一個普通的頁眉、頁腳,并居中顯示
          ????:param?header_content:
          ????:param?footer_content:
          ????:return:
          ????"""

          ????#?新增/修改頁眉、頁腳
          ????#?注意:一般頁眉、頁腳里只有一個段落
          ????header.paragraphs[0].text?=?header_content
          ????footer.paragraphs[0].text?=?footer_content

          ????#?居中顯示
          ????header.paragraphs[0].alignment?=?WD_PARAGRAPH_ALIGNMENT.CENTER
          ????footer.paragraphs[0].alignment?=?WD_PARAGRAPH_ALIGNMENT.CENTER

          #?2、新增頁眉
          #?2.1?普通的頁眉、頁腳
          add_norm_header_and_footer(header,?footer,?"我是一個頁眉",?"我是一個頁腳")

          2 - 自帶樣式的頁眉頁腳

          def?add_custom_style_header_and_footer(header,?footer,?header_content,?footer_content,?style):
          ????"""
          ????新增自定義的頁眉、頁腳
          ????:param?header:
          ????:param?footer:
          ????:param?header_content:
          ????:param?footer_content:
          ????:param?style:
          ????:return:
          ????"""

          ????#?注意:style_type=2,否則會報錯
          ????header.paragraphs[0].add_run(header_content,?style)
          ????footer.paragraphs[0].add_run(footer_content,?style)

          #?2.2?自帶樣式的頁眉、頁腳
          #?創(chuàng)建一個樣式
          style_paragraph?=?create_style(document=self.doc,?style_name="style5",?style_type=2,?font_size=30,
          ???????????????????????????????font_color=[0xff,?0x00,?0x00],?align=WD_PARAGRAPH_ALIGNMENT.CENTER)
          add_custom_style_header_and_footer(header,?footer,?"我是頁眉2",?"我是頁腳2",?style_paragraph)

          如果想將文檔中所有的頁眉、頁腳刪除掉,只需要 2 個步驟:

          • 遍歷文檔中所有頁面章節(jié),將其?different_first_page_header_footer 屬性值設(shè)置為 False

          • 設(shè)置章節(jié)對象頁眉頁腳的?is_linked_to_previous 屬性值為 True

            PS:當 is_linked_to_previous 設(shè)置為 True 時,頁眉頁腳會被刪除

          def?remove_all_header_and_footer(doc):
          ????"""
          ????刪除文檔中所有頁眉和頁腳
          ????:param?doc:
          ????:return:
          ????"""

          ????for?section?in?doc.sections:
          ????????section.different_first_page_header_footer?=?False
          ????????#?當is_linked_to_previous設(shè)置為True時,頁眉頁腳會被刪除
          ????????section.header.is_linked_to_previous?=?True
          ????????section.footer.is_linked_to_previous?=?True

          3. 合并多個文檔

          日常工作中,經(jīng)常會遇到將多個 Word 文檔合并成一個文件的需求

          這里,可以使用另外一個 Python 依賴庫:docxcompose

          #?合并多個文件的依賴庫
          #?pip3?install?docxcompose

          使用也非常簡單,只需要下面 4?行代碼,就能將多個文件進行合并,生成到一個新的文件中去

          from?docxcompose.composer?import?Composer

          def?compose_files(self,?files,?output_file_path):
          ????"""
          ????合并多個word文件到一個文件中
          ????:param?files:待合并文件的列表
          ????:param?output_file_path?新的文件路徑
          ????:return:
          ????"""

          ????composer?=?Composer(Document())
          ????for?file?in?files:
          ????????composer.append(Document(file))

          ????#?保存到新的文件中
          ????composer.save(output_file_path)

          4. 新增數(shù)字索引

          我們經(jīng)常需要在文檔頁腳處添加頁面數(shù)字索引,可惜 python-docx 并沒有提供現(xiàn)有方法

          但是,在?stackoverflow 上找到實現(xiàn)的方式

          https://stackoverflow.com/questions/56658872/add-page-number-using-python-docx?rq=1

          from?docx.oxml.xmlchemy?import?BaseOxmlElement,?ZeroOrOne,?ZeroOrMore,?OxmlElement
          from?docx.enum.text?import?WD_PARAGRAPH_ALIGNMENT
          from?docx.oxml?import?ns

          def?create_element(self,?name):
          ????return?OxmlElement(name)

          def?create_attribute(self,?element,?name,?value):
          ????element.set(ns.qn(name),?value)

          def?add_page_number(self,?run):
          ????"""
          ????添加頁面索引
          ????:param?run:
          ????:return:
          ????"""

          ????fldChar1?=?self.create_element('w:fldChar')
          ????self.create_attribute(fldChar1,?'w:fldCharType',?'begin')

          ????instrText?=?self.create_element('w:instrText')
          ????self.create_attribute(instrText,?'xml:space',?'preserve')
          ????instrText.text?=?"PAGE"

          ????fldChar2?=?self.create_element('w:fldChar')
          ????self.create_attribute(fldChar2,?'w:fldCharType',?'end')

          ????# run._r:class 'docx.oxml.text.run.CT_R'>
          ????run._r.append(fldChar1)
          ????run._r.append(instrText)
          ????run._r.append(fldChar2)

          默認生成的數(shù)字索引在頁腳左下角,并不美觀!

          因此,這里我們可以使用?第一篇文章?的方法創(chuàng)建一個文字塊樣式」,然后以文字塊 Run 的形式,添加到頁腳的第一個段落中去

          #?注意:要設(shè)置頁眉頁腳的對齊方式,必須設(shè)置到段落上(文字塊不能添加對齊方式)
          doc.sections[0].footer.paragraphs[0].alignment?=?WD_PARAGRAPH_ALIGNMENT.CENTER

          #?創(chuàng)建一個文字塊樣式,指定字體名稱、大小、顏色
          style?=?create_style(document=doc,?style_name="style",?style_type=2,?font_size=10,
          ?????????????????????font_color=[0x00,?0x00,?0x00],?font_name="黑體")
          self.add_page_number(doc.sections[0].footer.paragraphs[0].add_run("",?style))
          doc.save("./output.docx")
          print('添加頁碼索引成功!')

          需要注意的,如果需要設(shè)置頁面數(shù)字索引的對齊方式,必須針對頁腳的段落進行設(shè)置,修改其 alignment 屬性值即可

          5. doc 轉(zhuǎn) docx

          python-docx 對?doc 格式的文檔不太友好,要處理這類文檔,我們需要先將它轉(zhuǎn)換為 docx 格式

          對于 Windows 系統(tǒng),完全可以使用 win32com 這個模塊,用命令去調(diào)用 Word 應(yīng)用,打開源文件后,保存了 docx 格式的文件即可

          from?win32com?import?client

          def?doc_to_docx_in_win(path_raw,?path_output):
          ????"""
          ????doc轉(zhuǎn)為docx(win)
          ????:param?path_original:
          ????:param?path_final:
          ????:return:
          ????"""

          ????#?獲取文件的格式后綴
          ????file_suffix?=?os.path.splitext(path_raw)[1]
          ????if?file_suffix?==?".doc":
          ????????word?=?client.Dispatch('Word.Application')
          ????????#?源文件
          ????????doc?=?word.Documents.Open(path_raw)
          ????????#?生成的新文件
          ????????doc.SaveAs(path_output,?16)
          ????????doc.Close()
          ????????word.Quit()
          ????elif?file_suffix?==?".docx":
          ????????shutil.copy(path_raw,?path_output)

          而對于 Mac/Linux,推薦使用?LibreOffice 去轉(zhuǎn)換文檔格式

          #?轉(zhuǎn)換格式
          ./soffice?--headless?--convert-to?docx?源文件.doc?--outdir?/output/path/

          PS:LibreOffice?是一款由社區(qū)創(chuàng)造的自由免費辦公套件,跨平臺,內(nèi)置的?soffice?可以用于文件轉(zhuǎn)換

          以 Mac OS 為例,我們按下面步驟來操作

          • 官網(wǎng)下載?LibreOffice 軟件并安裝

          • 找到?LibreOffice?軟件安裝目錄,將 soffice 命令所在目錄配置到環(huán)境變量中

          • 重啟 Pycharm

          • 使用 os?模塊下的 walk() 函數(shù)遍歷所有源文件,組成一條?soffice 轉(zhuǎn)換命令

          • 執(zhí)行轉(zhuǎn)換命令

          import?os

          source?=?"./doc/"
          dest?=?"./docx/"
          g?=?os.walk(source)

          #?遍歷文件夾
          for?root,?dirs,?files?in?g:
          ????for?file?in?files:
          ????????#?源文件完整路徑
          ????????file_path_raw?=?os.path.join(root,?file)
          ????????print(file_path_raw)

          ????????os.system("soffice?--headless?--convert-to?docx?{}?--outdir?{}".format(file_path_raw,?dest))

          6. 對比文檔差異性

          兩個 Word 文檔的對比也是工作中比較常見的需求了

          首先,遍歷文檔中所有段落,過濾掉空行,獲取所有文本內(nèi)容

          #?分別獲取段落內(nèi)容
          content1?=?''
          content2?=?''
          for?paragraph?in?file1.paragraphs:
          ????if?""?==?paragraph.text.strip():
          ????????continue
          ????content1?+=?paragraph.text?+?'\n'

          for?paragraph?in?file2.paragraphs:
          ????if?""?==?paragraph.text.strip():
          ????????continue
          ????content2?+=?paragraph.text?+?'\n'

          #?如果參數(shù) keepends 為 False,不包含換行符,如果為 True,則保留換行符。
          print("第二個文檔數(shù)據(jù)如下:\n",?content1.splitlines(keepends=False))
          print("第一個文檔數(shù)據(jù)如下:\n",?content1.splitlines(keepends=False))

          接著,使用 Python 中的標準依賴庫?difflib?對比文字間的差異,最后生成 HTML 差異報告

          import?codecs
          from?difflib?import?HtmlDiff

          #?差異內(nèi)容
          diff_html?=?HtmlDiff(wrapcolumn=100).make_file(content1.split("\n"),?content2.split("\n"))

          #?寫入到文件中
          with?codecs.open('./diff_result.html',?'w',?encoding='utf-8')?as?f:
          ?????f.write(diff_html)

          7. 特別內(nèi)容標注

          我們經(jīng)常需要對文檔中部分重要內(nèi)容進行特別標注

          比如,我們需要對文檔中包含「 微信?」的文字塊或單元格,標為紅色并加粗顯示

          1 - 段落內(nèi)容

          只需要遍歷出段落中所有文字塊 Run,直接修改文字塊的?Font?屬性即可

          doc?=?Document(file)

          #?關(guān)鍵字的文字塊或單元格標紅,并加粗
          #?1、修改段落中包含關(guān)鍵字的文件塊的樣式
          for?paragraph?in?doc.paragraphs:
          ????for?run?in?paragraph.runs:
          ????????if?keyword?in?run.text:
          ????????????#?修改顏色為紅色,并加粗顯示
          ????????????run.font.bold?=?True
          ????????????run.font.color.rgb?=?RGBColor(255,?0,?0)

          2 - 表格內(nèi)容

          設(shè)置滿足條件的單元格樣式有點特別,需要經(jīng)過下面 4 個步驟

          • 獲取單元格對象,獲取單元格文本內(nèi)容,并臨時保存

          • 清空單元格數(shù)據(jù)

          • 單元格對象追加一個段落和一個文字塊 Run,返回一個文字塊對象

          • 設(shè)置文字塊對象樣式,標紅并加粗

          tables?=?[table?for?table?in?doc.tables]
          for?table?in?tables:
          ????for?row?in?table.rows:
          ????????for?cell?in?row.cells:
          ????????????if?keyword?in?cell.text:
          ????????????????#?原內(nèi)容
          ????????????????content_raw?=?cell.text
          ????????????????#?清空單元格數(shù)據(jù)
          ????????????????cell.text?=?""
          ????????????????#?追加數(shù)據(jù)進去,并設(shè)置樣式
          ????????????????run?=?cell.paragraphs[0].add_run(content_raw)
          ????????????????run.font.color.rgb?=?RGBColor(255,?0,?0)
          ????????????????run.font.bold?=?True?

          8. 替換文字內(nèi)容

          有時候,我們需要將文檔中某個關(guān)鍵字全部替換成一個新的內(nèi)容

          這時候,我們可以遍歷所有段落和表格,使用?replace()?函數(shù)對段落文本和單元格內(nèi)容進行替換

          def?replace_content(self,?old_content,?new_content):
          ????"""
          ????替換文檔中所有內(nèi)容
          ????:param?old_content:舊的內(nèi)容
          ????:param?new_content:新的內(nèi)容
          ????:return:
          ????"""

          ????#?替換段落
          ????for?paragraph?in?self.doc.paragraphs:
          ????????if?old_content?in?paragraph.text:
          ????????????#?替換內(nèi)容后,重新設(shè)置進去
          ????????????paragraph.text?=?paragraph.text.replace(old_content,?new_content)

          ????#?替換表格
          ????# document.tables[表格索引].rows[行索引].cells[單元格列索引].text =?“新的數(shù)據(jù)”。
          ????tables?=?[table?for?table?in?self.doc.tables]
          ????for?table?in?tables:
          ????????for?row?in?table.rows:
          ????????????for?cell?in?row.cells:
          ????????????????if?old_content?in?cell.text:
          ????????????????????#?重新設(shè)置單元格內(nèi)容
          ????????????????????cell.text?=?cell.text.replace(old_content,?new_content)

          ????#?保存到一個新的文件中
          ????self.doc.save('./new.docx')

          9. 最后

          到此,Python 自動化 Word 篇的內(nèi)容全部結(jié)束了!

          如果實際工作中,有一些其他的業(yè)務(wù)場景文中沒有覆蓋到,可以在文末進行留言,后面辦公自動化實戰(zhàn)篇可能會提供對應(yīng)的解決方案!

          要獲取全部源碼,關(guān)注公眾號,后臺回復(fù)「?word?」即可獲得全部源碼

          如果你覺得文章還不錯,請大家?點贊、分享、留言?下,因為這將是我持續(xù)輸出更多優(yōu)質(zhì)文章的最強動力!


          留言送書

          本周贈書:《?Python數(shù)據(jù)分析入門到項目實戰(zhàn)
          內(nèi)容簡介:本書講解主要以Python數(shù)據(jù)分析相關(guān)內(nèi)容為主,還涉及數(shù)據(jù)分析背后的數(shù)學思維。全書內(nèi)容主要分為三部分。#一部分為Python數(shù)據(jù)分析相關(guān)技能,包括NumPy、pandas等重要的三方庫的使用技巧;二部分為數(shù)據(jù)分析相關(guān)統(tǒng)計學知識,主要包含構(gòu)建模型的流程、思路,以及數(shù)學原理的解析;三部分為實戰(zhàn),主要是結(jié)合Python數(shù)據(jù)分析工具與統(tǒng)計學知識的實踐作

          PS:中獎名單將于下周一在交流群公布



          推薦閱讀


          最全總結(jié) | 聊聊 Python 辦公自動化之 Excel(上)

          最全總結(jié) | 聊聊 Python 辦公自動化之 Excel(中)

          最全總結(jié) | 聊聊 Python 辦公自動化之 Excel(下)

          最全總結(jié) | 聊聊 Python 辦公自動化之 Word(上)

          最全總結(jié) | 聊聊 Python 辦公自動化之 Word(中)



          瀏覽 66
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  免费看日逼视频的网站 | 大雞巴弄得我好舒服黃片动漫版 | 欧美亚洲中文 | 影音先锋三级资源 | www97色色 |