1. 程式人生 > 實用技巧 >一個可以選擇目錄生成doc目錄內容的小工具(三) -python-docx

一個可以選擇目錄生成doc目錄內容的小工具(三) -python-docx

說到docx的用法,度娘一大堆,眼花繚亂的。這裡就不囉嗦了,基本上就是新建個Document物件,然後往上邊加標題、段落、表格。附帶設定這些物件的字型字號啥的。不過有一點,docx和python-docx是兩個庫,看帖的時候要小心。建議看官方文件

接著看看我們的目標:

為了實現這種編號,我先是想修改本地docx的樣式來解決,生成文件的時候只設置成幾級標題,不設定任何樣式,在本機修改預設樣式模板。結果,沒啥用。
然後我想會不會在docx的標題樣式裡有相關的設定,然後就找到了這個

編號樣式還沒有實現,果然大神研發鄙視python還是有道理的。那現在只能從樣式模板上入手了,找了半天也沒有發現指定模板的的方法,docx庫的預設模板和本地的模板不是指一個東東。
無奈了,最後選擇笨辦法,手工賦值:比較難受的是因為要操作全域性變數取編號,但目錄和廣度和深度都是不確定因素,所以只能定死。
思路就是使用全域性變數n來判斷目錄的廣度,使用num確定目錄的深度,讀取各個全域性變數listxx裡的編號將編號加到item名前。如果有更美觀的實現方式,請諸位看客一定留言告知。


程式碼如下:

import os
import os.path

from docx import Document
from docx.enum.style import WD_STYLE_TYPE
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
from docx.oxml.ns import qn
from docx.shared import Inches, Pt, RGBColor

#初始化doc物件、
def Init():
    global doc
    doc = Document()
    doc.styles["Normal"].font.name = u'宋體'
    doc.styles["Normal"].font.size = Pt(12)
    doc.styles["Normal"]._element.rPr.rFonts.set(qn('w:eastAsia'), u'宋體')
    doc.styles["heading 1"].font.size=Pt(20)


    name = doc.add_paragraph()
    run = name.add_run(r'本週主要內容')
    run.font.size = Pt(25)
    run.font.name = u"宋體"
    run._element.rPr.rFonts.set(qn('w:eastAsia'), u'宋體')
    name.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER

    # head = doc.add_heading("", level=1)
    # run = head.add_run(u"主要內容")
    # run.font.size = Pt(12)
    # run.font.color.rgb = RGBColor(0, 0, 0)
    # run.font.name = u"宋體"
    # run._element.rPr.rFonts.set(qn('w:eastAsia'), u'宋體')
    # head.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER

def Save(dst):
    global doc
    try:
        doc.save(dst)
        return True
    except IOError as e:
        last_err = e.strerror
        return False

#設定段落
def AddListText(text):
    global doc
    p = doc.add_paragraph(style='List Number')
    run = p.add_run(text)
    run.font.size = Pt(15)
    run.font.name = u"宋體"
    run._element.rPr.rFonts.set(qn('w:eastAsia'), u'宋體')

def AddLineText(text):
    global doc
    name = doc.add_paragraph(style='List Number')
    run = name.add_run(text)
    run.font.size = Pt(15)
    run.font.name = u"宋體"
    run._element.rPr.rFonts.set(qn('w:eastAsia'), u'宋體')

global numlist1,numlist2,numlist22,numlist3,numlist33,n
n = 0
numlist1 = ['一、','二、','三、','四、','五、','六、','七、','八、','九、','十、']
numlist2 = ['(一)、', '(二)、', '(三)、', '(四)、', '(五)、', '(六)、', '(七)、', '(八)、', '(九)、', '(十)、']
numlist22 = ['(一)、', '(二)、', '(三)、', '(四)、', '(五)、', '(六)、', '(七)、', '(八)、', '(九)、', '(十)、']
numlist3 = ['1、','2、','3、','4、','5、','6、','7、','8、','9、','10、']
numlist33 = ['1、','2、','3、','4、','5、','6、','7、','8、','9、','10、']

def Addhead(text,num):
    global doc

    if num == 1 :
        listnum = num - 1
        head = doc.add_heading("", level=num)
        run = head.add_run(numlist1.pop(listnum)+text)
        run.font.name = u"宋體"
    elif num == 2:
        listnum = num - 2
        head = doc.add_heading("", level=num)
        print(n)
        if n == 1:
            try:
                run = head.add_run(numlist2.pop(listnum) + text)
            except Exception as e:
                print(e)
            run.font.name = u"宋體"
        else:
            try:
                run = head.add_run(numlist22.pop(listnum) + text)
            except Exception as e:
                print(e)

            run.font.name = u"宋體"

    elif num == 3:
        listnum = num - 3

        if n == 1:
            head = doc.add_heading("", level=num)
            run = head.add_run(numlist3.pop(listnum) + text)
            run.font.name = u"宋體"
        else:
            head = doc.add_heading("", level=num)
            run = head.add_run(numlist33.pop(listnum) + text)
            run.font.name = u"宋體"

Init()
def _showdir(path, depth):

    for item in os.scandir(path):
        # AddListText(item.name)
        print("|     " * depth + "+--" + item.name)
        # AddLineText("     " * depth + "   " + item.name)
        Addhead(item.name, depth + 1)
        #遞迴出口
        if item.is_dir():
            _showdir(item.path, depth + 1)


def showdir(path, depth):
    for item in os.scandir(path):
        global n
        n += 1
        print("|     " * depth + "+--" + item.name)

        Addhead(item.name, depth + 1)
        #遞迴出口
        if item.is_dir():
            _showdir(item.path, depth + 1)

    file = r'C:\Users\zhaobw\Desktop\demo.docx'
    Save(file)

if __name__ == '__main__':
    path = r'C:\Users\zhaobw\Desktop\測試'
    showdir(path, 0)
    # showlistdir(path, 0)

總結:
這一節完後了docx的測試,需求基本上都已經完成了。下一步將邏輯程式碼貼到gui裡,或者呼叫都可以。