1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205
|
# encoding: utf-8
"""|Document| and closely related objects"""
from __future__ import absolute_import, division, print_function, unicode_literals
from docx.blkcntnr import BlockItemContainer
from docx.enum.section import WD_SECTION
from docx.enum.text import WD_BREAK
from docx.section import Section, Sections
from docx.shared import ElementProxy, Emu
class Document(ElementProxy):
"""WordprocessingML (WML) document.
Not intended to be constructed directly. Use :func:`docx.Document` to open or create
a document.
"""
__slots__ = ('_part', '__body')
def __init__(self, element, part):
super(Document, self).__init__(element)
self._part = part
self.__body = None
def add_heading(self, text="", level=1):
"""Return a heading paragraph newly added to the end of the document.
The heading paragraph will contain *text* and have its paragraph style
determined by *level*. If *level* is 0, the style is set to `Title`. If *level*
is 1 (or omitted), `Heading 1` is used. Otherwise the style is set to `Heading
{level}`. Raises |ValueError| if *level* is outside the range 0-9.
"""
if not 0 <= level <= 9:
raise ValueError("level must be in range 0-9, got %d" % level)
style = "Title" if level == 0 else "Heading %d" % level
return self.add_paragraph(text, style)
def add_page_break(self):
"""Return newly |Paragraph| object containing only a page break."""
paragraph = self.add_paragraph()
paragraph.add_run().add_break(WD_BREAK.PAGE)
return paragraph
def add_paragraph(self, text='', style=None):
"""
Return a paragraph newly added to the end of the document, populated
with *text* and having paragraph style *style*. *text* can contain
tab (``\\t``) characters, which are converted to the appropriate XML
form for a tab. *text* can also include newline (``\\n``) or carriage
return (``\\r``) characters, each of which is converted to a line
break.
"""
return self._body.add_paragraph(text, style)
def add_picture(self, image_path_or_stream, width=None, height=None):
"""
Return a new picture shape added in its own paragraph at the end of
the document. The picture contains the image at
*image_path_or_stream*, scaled based on *width* and *height*. If
neither width nor height is specified, the picture appears at its
native size. If only one is specified, it is used to compute
a scaling factor that is then applied to the unspecified dimension,
preserving the aspect ratio of the image. The native size of the
picture is calculated using the dots-per-inch (dpi) value specified
in the image file, defaulting to 72 dpi if no value is specified, as
is often the case.
"""
run = self.add_paragraph().add_run()
return run.add_picture(image_path_or_stream, width, height)
def add_section(self, start_type=WD_SECTION.NEW_PAGE):
"""
Return a |Section| object representing a new section added at the end
of the document. The optional *start_type* argument must be a member
of the :ref:`WdSectionStart` enumeration, and defaults to
``WD_SECTION.NEW_PAGE`` if not provided.
"""
new_sectPr = self._element.body.add_section_break()
new_sectPr.start_type = start_type
return Section(new_sectPr, self._part)
def add_table(self, rows, cols, style=None):
"""
Add a table having row and column counts of *rows* and *cols*
respectively and table style of *style*. *style* may be a paragraph
style object or a paragraph style name. If *style* is |None|, the
table inherits the default table style of the document.
"""
table = self._body.add_table(rows, cols, self._block_width)
table.style = style
return table
@property
def core_properties(self):
"""
A |CoreProperties| object providing read/write access to the core
properties of this document.
"""
return self._part.core_properties
@property
def inline_shapes(self):
"""
An |InlineShapes| object providing access to the inline shapes in
this document. An inline shape is a graphical object, such as
a picture, contained in a run of text and behaving like a character
glyph, being flowed like other text in a paragraph.
"""
return self._part.inline_shapes
@property
def paragraphs(self):
"""
A list of |Paragraph| instances corresponding to the paragraphs in
the document, in document order. Note that paragraphs within revision
marks such as ``<w:ins>`` or ``<w:del>`` do not appear in this list.
"""
return self._body.paragraphs
@property
def part(self):
"""
The |DocumentPart| object of this document.
"""
return self._part
def save(self, path_or_stream):
"""
Save this document to *path_or_stream*, which can be either a path to
a filesystem location (a string) or a file-like object.
"""
self._part.save(path_or_stream)
@property
def sections(self):
"""|Sections| object providing access to each section in this document."""
return Sections(self._element, self._part)
@property
def settings(self):
"""
A |Settings| object providing access to the document-level settings
for this document.
"""
return self._part.settings
@property
def styles(self):
"""
A |Styles| object providing access to the styles in this document.
"""
return self._part.styles
@property
def tables(self):
"""
A list of |Table| instances corresponding to the tables in the
document, in document order. Note that only tables appearing at the
top level of the document appear in this list; a table nested inside
a table cell does not appear. A table within revision marks such as
``<w:ins>`` or ``<w:del>`` will also not appear in the list.
"""
return self._body.tables
@property
def _block_width(self):
"""
Return a |Length| object specifying the width of available "writing"
space between the margins of the last section of this document.
"""
section = self.sections[-1]
return Emu(
section.page_width - section.left_margin - section.right_margin
)
@property
def _body(self):
"""
The |_Body| instance containing the content for this document.
"""
if self.__body is None:
self.__body = _Body(self._element.body, self)
return self.__body
class _Body(BlockItemContainer):
"""
Proxy for ``<w:body>`` element in this document, having primarily a
container role.
"""
def __init__(self, body_elm, parent):
super(_Body, self).__init__(body_elm, parent)
self._body = body_elm
def clear_content(self):
"""
Return this |_Body| instance after clearing it of all content.
Section properties for the main document story, if present, are
preserved.
"""
self._body.clear_content()
return self
|