- Saved searches
- Use saved searches to filter your results more quickly
- autofit is broken #209
- autofit is broken #209
- Comments
- Table Properties¶
- Autofit¶
- Specimen XML¶
- Layout behavior¶
- Semantics of CT_TblWidth element¶
- Schema Definitions¶
- Table of Contents
- Table objects¶
- Table objects¶
- _Cell objects¶
- _Row objects¶
- _Column objects¶
- _Rows objects¶
- _Columns objects¶
- Table of Contents
Saved searches
Use saved searches to filter your results more quickly
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session. You switched accounts on another tab or window. Reload to refresh your session.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
autofit is broken #209
autofit is broken #209
Comments
Hi, the autofit method is broken in 0.8.5. Tables behave like if the columns have fixed width.
When autofit is set, tag(s) for the table(s) in document.xml should be set to something like and not (for example)
The text was updated successfully, but these errors were encountered:
yes I iterate and fix widths manually
Okay, thank you for the quick reply. I am doing the same as I can’t find another way to accomplish this. Thank you again.
What XML do you get for the table object in question after setting autofit True?
tbl = table._tbl print(tbl.xml)
I think you’ll find this is a limitation on how Word behaves rather than the XML not being to spec.
If I remember correctly, autofit only comes into things when you’re adjusting the columns with the UI. Word still records the actual width it ended up with in the XML and doesn’t recalculate it when the document is loaded.
Might be worth some investigation though. If there’s a way to improve the behavior I’d be keen to know about it and get it into an enhancement request.
Hi,
Word’s autofit is triggered when the document is opened 😉
You can do this single test :
create a new document with a signe table with some content, change its property to «autofit», save the doc.
unzip the doc, modify document.xml in subdirectory «word» -> find an existing cell with some content, add a bigger string.
zip again the whole directory with a .docx name
open it again in Word and Tada !
😉
How does the XML compare between what works in Word and what doesn’t in python-docx?
@scanny the difference in the XML is
w:tcW w:w="0" w:type="auto"/> compared to w:tcW w:w="1377" w:type="dxa"/>
@SebastienGutierrez is absolutely right, I created a small script to create a .docx-file demonstrating the problem for tables with and without autofit.
- Whitespaces contribute to the problem and have to be included in test cases when trying to fix the problem.
- The expected autofit-behaviour is achieved by replacing type=»dxa»‘with ‘type=»auto» in word/document.xml
- table.autofit =False allways works as expected
Obviously this is not a proper solution, since there are several other occurences of ‘dxa’ in the code, thus replacing might destroy files other than my very simple test case (I have tried some other files without any problems).
I think CT_tbl._tcs_xml() in table.py has to be adjusted, but I just couldn’t figure out how all the classes work together.
from docx import Document from zipfile import ZipFile document_file = 'AutofitTest.docx' fixed_document_file = 'AutofitTest_fixed.docx' doc = Document() for autofit in [True, False]: doc.add_heading('Table with autofit = ' + str(autofit), 1) for text in ['NoWhiteSpaces', ' whitespaces ']: doc.add_heading('Test table: ' + text, 2) table = doc.add_table(2,2) table.autofit = autofit for row in table.rows: for cell, cell_text in zip(row.cells, ['A', 5 * text]): cell.text = cell_text doc.add_paragraph() doc.save(document_file) # Replacing type="dxa"'with 'type="auto" in word/document.xml with ZipFile(document_file, 'r') as myzip: with ZipFile(fixed_document_file, 'w') as myzip_out: for f in myzip.namelist(): data = myzip.read(f) if f == 'word/document.xml': data = data.replace(b'type="dxa"', b'type="auto"') myzip_out.writestr(f, data)
Table Properties¶
Word allows a table to be aligned between the page margins either left, right, or center.
The read/write Table.alignment property specifies the alignment for a table:
>>> table = document.add_table(rows=2, cols=2) >>> table.alignment None >>> table.alignment = WD_TABLE_ALIGNMENT.RIGHT >>> table.alignment RIGHT (2)
Autofit¶
Word has two algorithms for laying out a table, fixed-width or autofit. The default is autofit. Word will adjust column widths in an autofit table based on cell contents. A fixed-width table retains its column widths regardless of the contents. Either algorithm will adjust column widths proportionately when total table width exceeds page width.
The read/write Table.allow_autofit property specifies which algorithm is used:
>>> table = document.add_table(rows=2, cols=2) >>> table.allow_autofit True >>> table.allow_autofit = False >>> table.allow_autofit False
Specimen XML¶
The following XML represents a 2×2 table:
w:val="TableGrid"/> w:type="auto" w:w="0"/> w:val="right"/> w:firstColumn="1" w:firstRow="1" w:lastColumn="0" w:lastRow="0" w:noHBand="0" w:noVBand="1" w:val="04A0"/> w:w="4788"/> w:w="4788"/> w:type="dxa" w:w="4788"/> w:type="dxa" w:w="4788"/> w:type="dxa" w:w="4788"/> w:type="dxa" w:w="4788"/>
Layout behavior¶
Auto-layout causes actual column widths to be both unpredictable and unstable. Changes to the content can make the table layout shift.
Semantics of CT_TblWidth element¶
w:w="42.4mm"/> w:w="1800" w:type="dxa"/> w:w="20%" w:type="pct"/> w:w="0" w:type="auto"/> w:type="nil"/> ST_MeasurementOrPercent | +-- ST_DecimalNumberOrPercent | | | +-- ST_UnqualifiedPercentage | | | | | +-- XsdInteger e.g. '1440' | | | +-- ST_Percentage e.g. '-07.43%' | +-- ST_UniversalMeasure e.g. '-04.34mm'
Schema Definitions¶
name="CT_Tbl"> ref="EG_RangeMarkupElements" minOccurs="0" maxOccurs="unbounded"/> name="tblPr" type="CT_TblPr"/> name="tblGrid" type="CT_TblGrid"/> minOccurs="0" maxOccurs="unbounded"> name="tr" type="CT_Row"/> name="customXml" type="CT_CustomXmlRow"/> name="sdt" type="CT_SdtRow"/> ref="EG_RunLevelElts" minOccurs="0" maxOccurs="unbounded"/> name="CT_TblPr"> name="tblStyle" type="CT_String" minOccurs="0"/> name="tblpPr" type="CT_TblPPr" minOccurs="0"/> name="tblOverlap" type="CT_TblOverlap" minOccurs="0"/> name="bidiVisual" type="CT_OnOff" minOccurs="0"/> name="tblStyleRowBandSize" type="CT_DecimalNumber" minOccurs="0"/> name="tblStyleColBandSize" type="CT_DecimalNumber" minOccurs="0"/> name="tblW" type="CT_TblWidth" minOccurs="0"/> name="jc" type="CT_JcTable" minOccurs="0"/> name="tblCellSpacing" type="CT_TblWidth" minOccurs="0"/> name="tblInd" type="CT_TblWidth" minOccurs="0"/> name="tblBorders" type="CT_TblBorders" minOccurs="0"/> name="shd" type="CT_Shd" minOccurs="0"/> name="tblLayout" type="CT_TblLayoutType" minOccurs="0"/> name="tblCellMar" type="CT_TblCellMar" minOccurs="0"/> name="tblLook" type="CT_TblLook" minOccurs="0"/> name="tblCaption" type="CT_String" minOccurs="0"/> name="tblDescription" type="CT_String" minOccurs="0"/> name="tblPrChange" type="CT_TblPrChange" minOccurs="0"/> name="CT_JcTable"> name="val" type="ST_JcTable" use="required"/> name="ST_JcTable"> base="xsd:string"> value="center"/> value="end"/> value="left"/> value="right"/> value="start"/> name="CT_TblWidth"> name="w" type="ST_MeasurementOrPercent"/> name="type" type="ST_TblWidth"/> name="ST_MeasurementOrPercent"> memberTypes="ST_DecimalNumberOrPercent s:ST_UniversalMeasure"/> name="ST_DecimalNumberOrPercent"> memberTypes="ST_UnqualifiedPercentage s:ST_Percentage"/> name="ST_UniversalMeasure"> base="xsd:string"> value="-?8+(\.3+)?(mm|cm|in|pt|pc|pi)"/> name="ST_UnqualifiedPercentage"> base="xsd:integer"/> name="ST_Percentage"> base="xsd:string"> value="-?1+(\.6+)?%"/> name="ST_TblWidth"> base="xsd:string"> value="nil"/> value="pct"/> value="dxa"/> value="auto"/> name="CT_TblLayoutType"> name="type" type="ST_TblLayoutType"/> name="ST_TblLayoutType"> base="xsd:string"> value="fixed"/> value="autofit"/> name="CT_TblLook"> name="firstRow" type="s:ST_OnOff"/> name="lastRow" type="s:ST_OnOff"/> name="firstColumn" type="s:ST_OnOff"/> name="lastColumn" type="s:ST_OnOff"/> name="noHBand" type="s:ST_OnOff"/> name="noVBand" type="s:ST_OnOff"/> name="val" type="ST_ShortHexNumber"/>
Table of Contents
Table objects¶
Table objects are constructed using the add_table() method on Document .
Table objects¶
Proxy class for a WordprocessingML element.
Return a _Column object of width, newly added rightmost to the table.
Return a _Row instance, newly added bottom-most to the table.
Read/write. A member of WD_TABLE_ALIGNMENT or None, specifying the positioning of this table between the page margins. None if no setting is specified, causing the effective value to be inherited from the style hierarchy.
True if column widths can be automatically adjusted to improve the fit of cell contents. False if table layout is fixed. Column widths are adjusted in either case if total column width exceeds page width. Read/write boolean.
Return _Cell instance correponding to table cell at row_idx, col_idx intersection, where (0, 0) is the top, left-most cell.
Sequence of cells in the column at column_idx in this table.
_Columns instance representing the sequence of columns in this table.
Sequence of cells in the row at row_idx in this table.
_Rows instance containing the sequence of rows in this table.
Read/write. A _TableStyle object representing the style applied to this table. The default table style for the document (often Normal Table ) is returned if the table has no directly-applied style. Assigning None to this property removes any directly-applied table style causing it to inherit the default table style of the document. Note that the style name of a table style differs slightly from that displayed in the user interface; a hyphen, if it appears, must be removed. For example, Light Shading — Accent 1 becomes Light Shading Accent 1 .
A member of WD_TABLE_DIRECTION indicating the direction in which the table cells are ordered, e.g. WD_TABLE_DIRECTION.LTR . None indicates the value is inherited from the style hierarchy.
_Cell objects¶
Return a paragraph newly added to the end of the content in this cell. If present, text is added to the paragraph in a single run. If specified, the paragraph style style is applied. If style is not specified or is None , the result is as though the ‘Normal’ style was applied. Note that the formatting of text in a cell can be influenced by the table 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 a table newly added to this cell after any existing cell content, having rows rows and cols columns. An empty paragraph is added after the table because Word requires a paragraph element as the last element in every cell.
Return a merged cell created by spanning the rectangular region having this cell and other_cell as diagonal corners. Raises InvalidSpanError if the cells do not define a rectangular region.
List of paragraphs in the cell. A table cell is required to contain at least one block-level element and end with a paragraph. By default, a new cell contains a single paragraph. Read-only
List of tables in the cell, in the order they appear. Read-only.
The entire contents of this cell as a string of text. Assigning a string to this property replaces all existing content with a single paragraph containing the assigned text in a single run.
A value of None indicates vertical alignment for this cell is inherited. Assigning None causes any explicitly defined vertical alignment to be removed, restoring inheritance.
The width of this cell in EMU, or None if no explicit width is set.
_Row objects¶
Sequence of _Cell instances corresponding to cells in this row.
Return a Length object representing the height of this cell, or None if no explicit height is set.
Return the height rule of this cell as a member of the WD_ROW_HEIGHT_RULE enumeration, or None if no explicit height_rule is set.
Reference to the Table object this row belongs to.
_Column objects¶
Sequence of _Cell instances corresponding to cells in this column.
Reference to the Table object this column belongs to.
The width of this column in EMU, or None if no explicit width is set.
_Rows objects¶
Sequence of _Row objects corresponding to the rows in a table. Supports len() , iteration, indexed access, and slicing.
Reference to the Table object this row collection belongs to.
_Columns objects¶
Sequence of _Column instances corresponding to the columns in a table. Supports len() , iteration and indexed access.
Reference to the Table object this column collection belongs to.