将页眉与 Python - docx
Put Header with Python - docx
我正在使用 Python-docx 创建和编写 Word 文档。
如何使用 python-docx 将文本放入文档页眉?
http://image.prntscr.com/image/8757b4e6d6f545a5ab6a08a161e4c55e.png
谢谢
你可以header.text喜欢
header = section.header
header.text = 'foobar'
有关详细信息,请参阅 http://python-docx.readthedocs.io/en/latest/dev/analysis/features/header.html?highlight=header
更新:此功能自本回答时起已实施。
正如其他受访者在下面指出的那样,Section
object 提供对其 header object 的访问权限。
header = document.sections[0].header
请注意,一个部分最多可以有三个 header(first_page、odd_pages、even_pages),每个部分可以有自己的一组 header秒。最常见的情况是文档只有一个 header 和一个部分。
A header 类似于文档 body 或 table 单元格,因为它可以包含 tables and/or 段落并且默认情况下有一个空段落(不能包含零个段落)。
header.paragraphs[0].text = "My header text"
文档中的此页面对此进行了更详细的解释::
https://python-docx.readthedocs.io/en/latest/user/hdrftr.html
很遗憾,此功能尚未实现。 @SamRogers 链接到的页面是增强建议的一部分(又名“分析页面”)。但是,@eupharis 正在实施,因此可能会在一个月左右的时间内可用。如果您想关注正在进行的拉取请求,请点击此处。 https://github.com/python-openxml/python-docx/pull/291
(关于这个问题是旧的...)
我在我的项目中使用了 work-around,我的 "client" 希望在不同的页面中使用不同的 header:
使用 python-docx 和分节符创建文档
执行带有两个参数的word宏文件(*.xlsm): (1) fileName = path, docTitle = 要插入页脚的文档的标题。
宏文件将打开新创建的文档并添加宏文件中已有的 header 和页脚。如果 header 和页脚文本需要变化,则需要修改。
Pyton 代码:
wd = win32com.client.Dispatch("Word.Application")
wd.Visible = False
doc = wd.Documents.Open(pathToDOCM) # path here
wd.Run("Main.RunMain",fileName, docTitle) # 2 args
doc.Close()
del wd
VBA代码:
VBA (inside *.xlsm) code:
Sub RunInside()
Call RunMain("C:\Users\???\dokument.docx", "test")
End Sub
Sub RunMain(wordDocument As String, wordTitle As String)
' Create Headers
Call CreateHeaders(wordDocument, wordTitle)
End Sub
Sub CreateHeaders(wordDocument As String, wordTitle As String)
Dim i As Integer
Dim outputName As String
Dim aDoc As Document
Dim oApp As Word.Application
Dim oSec As Word.Section
Dim oDoc As Word.Document
Dim hdr1, hdr2 As HeaderFooter
Dim ftr1, ftr2 As HeaderFooter
'Create a new document in Word
Set oApp = New Word.Application
'Set oDoc = oApp.Documents.Add
Set oDoc = oApp.Documents.Open(wordDocument)
'Set aDoc as active document
Set aDoc = ActiveDocument
oDoc.BuiltInDocumentProperties("Title") = wordTitle
For i = 1 To 9:
Set hdr1 = aDoc.Sections(i).Headers(wdHeaderFooterPrimary)
Set hdr2 = oDoc.Sections(i).Headers(wdHeaderFooterPrimary)
Set ftr1 = aDoc.Sections(i).Footers(wdHeaderFooterPrimary)
Set ftr2 = oDoc.Sections(i).Footers(wdHeaderFooterPrimary)
If i > 1 Then
With oDoc.Sections(i).Headers(wdHeaderFooterPrimary)
.LinkToPrevious = False
End With
With oDoc.Sections(i).Footers(wdHeaderFooterPrimary)
.LinkToPrevious = False
End With
End If
hdr1.Range.Copy
hdr2.Range.Paste
ftr1.Range.Copy
ftr2.Range.Paste
Next i
outputName = Left(wordDocument, Len(wordDocument) - 5)
outputName = outputName + ".pdf"
oDoc.SaveAs outputName, 17
oDoc.Close SaveChanges:=wdSaveChanges
Set oDoc = Nothing
Set aDoc = Nothing
End Sub
最后的评论:
代码循环遍历不同的部分和 copy-paste header 和页脚。它还将文档保存为 *.PDF。
此功能已实现。参见:https://python-docx.readthedocs.io/en/latest/dev/analysis/features/header.html
您可以使用 python-docx 将文本添加到 word 文档的页眉,如下所示:
header = document.sections[0].header
head = header.paragraphs[0]
head.text = 'Add Your Text'
我一直在用它工作
header = document.sections[0].header
header.add_paragraph('Test Header')
Header是BlockItemContainer的子类,继承了与Document相同的内容编辑能力,如.add_paragraph().
import docx
document = docx.Document()
header_section = document.sections[0]
header = header_section.header
header_text = header.paragraphs[0]
header_text.text = "Header of document"
您可以使用\t
文本的任一侧将其居中对齐
对于那些希望设置自定义 headers w/docx:
的人
我不得不使用几个包来让它工作。我的用例是这样的:我正在生成多个模板,然后将它们合并在一起,但是当我将它们与 docx 合并时,主文件(下方)中的 header 被应用于所有部分,并且所有部分都被标记为 linkedToPrevious = True 尽管在原始文件中是 =False。然而,docx 在附加文件并在另一端输出 error-free 方面做得非常好,所以我决定找到一种方法让它工作。代码参考:
master = Document(files[0])
composer = Composer(master)
footnotes_doc = Document('chapters/footnotes.docx')
for file in files[1:]:
mergeDoc = Document(file)
composer.append(mergeDoc)
composer.append(footnotes_doc)
composer.save("chapters/combined.docx")
所以现在我有了一个包含所有正确部分的主文档 (combined.docx),但是 header 需要调整。您无法使用 docx 遍历文档,获取您所在的当前部分,并对其进行调整或将 headers 链接设置为 false。如果设置为 False,则会完全擦除 header。您可以显式调用该部分并对其进行调整,但由于它之后的所有内容都链接到之前的部分,因此您可以从该点更改文档的其余部分。所以我拉入了 win32com:
获取节数,然后使用 win32com 向后遍历它们。这样,当您删除 linkedToPrevious 时,您会保留 header。
def getSections(document):
sectionArray = {}
sections = document.sections
x = 1
for section in sections:
sectionArray[x] = section
x += 1
return sectionArray
start_doc = Document('chapters/combined.docx')
listArray = getSections(start_doc) #gets an array of all sections
keylist = list(reversed(sorted(listArray.keys()))) ##now reverse it
word = win32com.client.gencache.EnsureDispatch("Word.Application")
word = client.DispatchEx("Word.Application")
word.Visible = False
#tell word to open the document
word.Documents.Open(' C:\path to\combined.docx')
#open it internally
doc = word.Documents(1)
try:
for item in keylist:
word.ActiveDocument.Sections(item).Headers(win32com.client.constants.wdHeaderFooterPrimary).LinkToPrevious=False
word.ActiveDocument.Sections(item).Headers(win32com.client.constants.wdHeaderFooterEvenPages).LinkToPrevious=False
word.ActiveDocument.SaveAs("c:\wherever\combined_1.docx")
doc.Close()
word.Quit()
except:
doc.Close()
word.Quit()
好的,现在文档已准备好编辑 headers,我们现在可以使用 docx 轻松无忧地完成这些工作。首先,我们需要解析 XML,我使用 docx 访问它,然后将其提供给 lxml,以获取所需部分的位置:
xml = str(start_doc._element.xml) #this gets the full XML using docx
tree = etree.fromstring(xml)
WORD_NAMESPACE='{http://schemas.openxmlformats.org/wordprocessingml/2006/main}'
TEXT = WORD_NAMESPACE + 't'
PARA = WORD_NAMESPACE + 'p'
SECT = WORD_NAMESPACE + 'sectPr'
sectionLoc = []
for item in tree.iter(PARA):
for node in item.iter(TEXT):
if 'Section' in node.text: #this is how I am identifying which headers I need to edit
print(node.text)
sectionLoc.append(node.text)
for sect in item.iter(SECT):
print(sect)
sectionLoc.append('section')
# print(etree.tostring(sect))
counter =0
sectionLocs = []
for index, item in enumerate(sectionLoc): #just some logic to get the correct section number from the xml parse
if 'Section' in item:
sectionLocs.append(counter)
continue
counter += 1
#ok now use those locations with docx to adjust the headers
#remember that start_doc here needs to be the new result from win32 process-
#so start_doc = Document('C:\path to\combined.docx') in this case
for item in sectionLocs:
section = start_doc.sections[item]
header = section.header
para_new = header.paragraphs[0]
para_new.text = 'TEST!'
start_doc.save('willthiswork.docx')
工作量很大。我敢打赌有一种方法可以完全用 win32com 来完成,但我无法根据页面 body 中的内容弄清楚如何获取相关部分。 “sectPr”标签总是出现在页面的末尾,所以在梳理文档的文本时,我知道页面上需要一个新的 header、“Section”,我知道下一个打印出来的部分是我要编辑的那个,所以我只得到它在列表中的位置。
我认为整个工作流程都是 hack,但它确实有效,我希望示例代码对某人有所帮助。
我正在使用 Python-docx 创建和编写 Word 文档。
如何使用 python-docx 将文本放入文档页眉?
http://image.prntscr.com/image/8757b4e6d6f545a5ab6a08a161e4c55e.png
谢谢
你可以header.text喜欢
header = section.header
header.text = 'foobar'
有关详细信息,请参阅 http://python-docx.readthedocs.io/en/latest/dev/analysis/features/header.html?highlight=header
更新:此功能自本回答时起已实施。
正如其他受访者在下面指出的那样,Section
object 提供对其 header object 的访问权限。
header = document.sections[0].header
请注意,一个部分最多可以有三个 header(first_page、odd_pages、even_pages),每个部分可以有自己的一组 header秒。最常见的情况是文档只有一个 header 和一个部分。
A header 类似于文档 body 或 table 单元格,因为它可以包含 tables and/or 段落并且默认情况下有一个空段落(不能包含零个段落)。
header.paragraphs[0].text = "My header text"
文档中的此页面对此进行了更详细的解释::
https://python-docx.readthedocs.io/en/latest/user/hdrftr.html
很遗憾,此功能尚未实现。 @SamRogers 链接到的页面是增强建议的一部分(又名“分析页面”)。但是,@eupharis 正在实施,因此可能会在一个月左右的时间内可用。如果您想关注正在进行的拉取请求,请点击此处。 https://github.com/python-openxml/python-docx/pull/291
(关于这个问题是旧的...)
我在我的项目中使用了 work-around,我的 "client" 希望在不同的页面中使用不同的 header:
使用 python-docx 和分节符创建文档
执行带有两个参数的word宏文件(*.xlsm): (1) fileName = path, docTitle = 要插入页脚的文档的标题。
宏文件将打开新创建的文档并添加宏文件中已有的 header 和页脚。如果 header 和页脚文本需要变化,则需要修改。
Pyton 代码:
wd = win32com.client.Dispatch("Word.Application")
wd.Visible = False
doc = wd.Documents.Open(pathToDOCM) # path here
wd.Run("Main.RunMain",fileName, docTitle) # 2 args
doc.Close()
del wd
VBA代码:
VBA (inside *.xlsm) code:
Sub RunInside()
Call RunMain("C:\Users\???\dokument.docx", "test")
End Sub
Sub RunMain(wordDocument As String, wordTitle As String)
' Create Headers
Call CreateHeaders(wordDocument, wordTitle)
End Sub
Sub CreateHeaders(wordDocument As String, wordTitle As String)
Dim i As Integer
Dim outputName As String
Dim aDoc As Document
Dim oApp As Word.Application
Dim oSec As Word.Section
Dim oDoc As Word.Document
Dim hdr1, hdr2 As HeaderFooter
Dim ftr1, ftr2 As HeaderFooter
'Create a new document in Word
Set oApp = New Word.Application
'Set oDoc = oApp.Documents.Add
Set oDoc = oApp.Documents.Open(wordDocument)
'Set aDoc as active document
Set aDoc = ActiveDocument
oDoc.BuiltInDocumentProperties("Title") = wordTitle
For i = 1 To 9:
Set hdr1 = aDoc.Sections(i).Headers(wdHeaderFooterPrimary)
Set hdr2 = oDoc.Sections(i).Headers(wdHeaderFooterPrimary)
Set ftr1 = aDoc.Sections(i).Footers(wdHeaderFooterPrimary)
Set ftr2 = oDoc.Sections(i).Footers(wdHeaderFooterPrimary)
If i > 1 Then
With oDoc.Sections(i).Headers(wdHeaderFooterPrimary)
.LinkToPrevious = False
End With
With oDoc.Sections(i).Footers(wdHeaderFooterPrimary)
.LinkToPrevious = False
End With
End If
hdr1.Range.Copy
hdr2.Range.Paste
ftr1.Range.Copy
ftr2.Range.Paste
Next i
outputName = Left(wordDocument, Len(wordDocument) - 5)
outputName = outputName + ".pdf"
oDoc.SaveAs outputName, 17
oDoc.Close SaveChanges:=wdSaveChanges
Set oDoc = Nothing
Set aDoc = Nothing
End Sub
最后的评论: 代码循环遍历不同的部分和 copy-paste header 和页脚。它还将文档保存为 *.PDF。
此功能已实现。参见:https://python-docx.readthedocs.io/en/latest/dev/analysis/features/header.html
您可以使用 python-docx 将文本添加到 word 文档的页眉,如下所示:
header = document.sections[0].header
head = header.paragraphs[0]
head.text = 'Add Your Text'
我一直在用它工作
header = document.sections[0].header
header.add_paragraph('Test Header')
Header是BlockItemContainer的子类,继承了与Document相同的内容编辑能力,如.add_paragraph().
import docx
document = docx.Document()
header_section = document.sections[0]
header = header_section.header
header_text = header.paragraphs[0]
header_text.text = "Header of document"
您可以使用\t
文本的任一侧将其居中对齐
对于那些希望设置自定义 headers w/docx:
的人我不得不使用几个包来让它工作。我的用例是这样的:我正在生成多个模板,然后将它们合并在一起,但是当我将它们与 docx 合并时,主文件(下方)中的 header 被应用于所有部分,并且所有部分都被标记为 linkedToPrevious = True 尽管在原始文件中是 =False。然而,docx 在附加文件并在另一端输出 error-free 方面做得非常好,所以我决定找到一种方法让它工作。代码参考:
master = Document(files[0])
composer = Composer(master)
footnotes_doc = Document('chapters/footnotes.docx')
for file in files[1:]:
mergeDoc = Document(file)
composer.append(mergeDoc)
composer.append(footnotes_doc)
composer.save("chapters/combined.docx")
所以现在我有了一个包含所有正确部分的主文档 (combined.docx),但是 header 需要调整。您无法使用 docx 遍历文档,获取您所在的当前部分,并对其进行调整或将 headers 链接设置为 false。如果设置为 False,则会完全擦除 header。您可以显式调用该部分并对其进行调整,但由于它之后的所有内容都链接到之前的部分,因此您可以从该点更改文档的其余部分。所以我拉入了 win32com:
获取节数,然后使用 win32com 向后遍历它们。这样,当您删除 linkedToPrevious 时,您会保留 header。
def getSections(document):
sectionArray = {}
sections = document.sections
x = 1
for section in sections:
sectionArray[x] = section
x += 1
return sectionArray
start_doc = Document('chapters/combined.docx')
listArray = getSections(start_doc) #gets an array of all sections
keylist = list(reversed(sorted(listArray.keys()))) ##now reverse it
word = win32com.client.gencache.EnsureDispatch("Word.Application")
word = client.DispatchEx("Word.Application")
word.Visible = False
#tell word to open the document
word.Documents.Open(' C:\path to\combined.docx')
#open it internally
doc = word.Documents(1)
try:
for item in keylist:
word.ActiveDocument.Sections(item).Headers(win32com.client.constants.wdHeaderFooterPrimary).LinkToPrevious=False
word.ActiveDocument.Sections(item).Headers(win32com.client.constants.wdHeaderFooterEvenPages).LinkToPrevious=False
word.ActiveDocument.SaveAs("c:\wherever\combined_1.docx")
doc.Close()
word.Quit()
except:
doc.Close()
word.Quit()
好的,现在文档已准备好编辑 headers,我们现在可以使用 docx 轻松无忧地完成这些工作。首先,我们需要解析 XML,我使用 docx 访问它,然后将其提供给 lxml,以获取所需部分的位置:
xml = str(start_doc._element.xml) #this gets the full XML using docx
tree = etree.fromstring(xml)
WORD_NAMESPACE='{http://schemas.openxmlformats.org/wordprocessingml/2006/main}'
TEXT = WORD_NAMESPACE + 't'
PARA = WORD_NAMESPACE + 'p'
SECT = WORD_NAMESPACE + 'sectPr'
sectionLoc = []
for item in tree.iter(PARA):
for node in item.iter(TEXT):
if 'Section' in node.text: #this is how I am identifying which headers I need to edit
print(node.text)
sectionLoc.append(node.text)
for sect in item.iter(SECT):
print(sect)
sectionLoc.append('section')
# print(etree.tostring(sect))
counter =0
sectionLocs = []
for index, item in enumerate(sectionLoc): #just some logic to get the correct section number from the xml parse
if 'Section' in item:
sectionLocs.append(counter)
continue
counter += 1
#ok now use those locations with docx to adjust the headers
#remember that start_doc here needs to be the new result from win32 process-
#so start_doc = Document('C:\path to\combined.docx') in this case
for item in sectionLocs:
section = start_doc.sections[item]
header = section.header
para_new = header.paragraphs[0]
para_new.text = 'TEST!'
start_doc.save('willthiswork.docx')
工作量很大。我敢打赌有一种方法可以完全用 win32com 来完成,但我无法根据页面 body 中的内容弄清楚如何获取相关部分。 “sectPr”标签总是出现在页面的末尾,所以在梳理文档的文本时,我知道页面上需要一个新的 header、“Section”,我知道下一个打印出来的部分是我要编辑的那个,所以我只得到它在列表中的位置。
我认为整个工作流程都是 hack,但它确实有效,我希望示例代码对某人有所帮助。