Open savaskoc opened 7 years ago
Interpretation of column widths varies between platforms (like LibreOffice, Google Docs, etc.)
If you set the width of each cell individually I think you'll get what you want across platforms.
--Steve
On Fri, Feb 3, 2017 at 1:48 PM, Savaş KOÇ notifications@github.com wrote:
Hi,
I have following table in my document;
table = self.add_table(rows=len(array), cols=4) table.columns[0].width = Cm(3) table.columns[1].width = Cm(11) table.columns[2].width = Cm(3) table.columns[3].width = Cm(3) for i, x in enumerate(array): table.cell(i, 0).text = 'Foo' table.cell(i, 1).text = 'Foo' table.cell(i, 2).text = 'Foo' table.cell(i, 2).paragraphs[0].paragraph_format.alignment = WD_ALIGN_PARAGRAPH.RIGHT table.cell(i, 3).text = 'Foo' table.cell(i, 3).paragraphs[0].paragraph_format.alignment = WD_ALIGN_PARAGRAPH.RIGHT
If I open the document in Apple Pages, all column widths are correct but not on MS Word. Am I missing something?
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/python-openxml/python-docx/issues/360, or mute the thread https://github.com/notifications/unsubscribe-auth/AB95fnhURHjTYLkZONhOimc3DRyO5aTwks5rY6DGgaJpZM4L22EA .
I did:
def set_column_width(table,column,width_mm):
table.allow_autofit = False
for row in table.rows:
row.cells[column].width = Mm(width_mm)
and the cells in Word get about 7mm larger than specified in python. Setting the width of each cell individually does not seem to give correct widths in word.
I'm not sure if the column width includes the internal cell margin or not. That could possibly account for the difference.
Setting the cell margins to 0 (manually in MS Word in the original document) does not change anything. Left and right cell margins are 1.9mm, but MS Word adds about 7 mm to the cell width.
In the following test, everything works perfectly
from docx import Document
from docx.shared import Mm
def set_column_width(table,column,width_mm):
table.allow_autofit = False
for row in table.rows:
row.cells[column].width = Mm(width_mm)
document = Document()
rows=4
cols=3
document.add_heading('Empty table - column 0 set to 25 mm width', level=1)
table = document.add_table(rows,cols)
set_column_width(table,0,25)
document.add_heading('Table with Text - column 0 set to 25 mm width',level=1)
table2=document.add_table(rows,cols)
for row in table2.rows:
for cell in row.cells:
cell.text=('here is some text')
set_column_width(table2,0,25)
document.save('C:/Users/ /tabletest.docx')`
In the original document may be some formatting waiting for discovery. I'm searching.
I read the original document, do some formatting with python-docx and write an output document. The column widths in the XML of the output document are correct. In dxa units.
Btw: this site is useful for unit conversion: http://lcorneliussen.de/raw/dashboards/ooxml/
Setting the widths of individual cells to 35 mm = 1984 dxa with python-docx gives:
<w:tbl>
<w:tblPr>
<w:tblW w:w="9288" w:type="dxa"/>
<w:tblBorders>
<w:top w:val="single" w:sz="4" w:space="0" w:color="auto"/>
<w:left w:val="single" w:sz="4" w:space="0" w:color="auto"/>
<w:bottom w:val="single" w:sz="4" w:space="0" w:color="auto"/>
<w:right w:val="single" w:sz="4" w:space="0" w:color="auto"/>
<w:insideH w:val="single" w:sz="4" w:space="0" w:color="auto"/>
<w:insideV w:val="single" w:sz="4" w:space="0" w:color="auto"/>
</w:tblBorders>
<w:tblLook w:val="0000" w:firstRow="0" w:lastRow="0" w:firstColumn="0" w:lastColumn="0" w:noHBand="0" w:noVBand="0"/>
</w:tblPr>
<w:tblGrid>
---> <w:gridCol w:w="3510"/>
<w:gridCol w:w="5778"/>
</w:tblGrid>
<w:tr w:rsidR="000A3B7A" w:rsidRPr="00046723" w:rsidTr="0089115F">
<w:tc>
<w:tcPr>
---> <w:tcW w:w="1984" w:type="dxa"/>
<w:shd w:val="clear" w:color="auto" w:fill="auto"/>
</w:tcPr>
<w:p>
<w:r>
<w:t>Arbeitsaufwand</w:t>
</w:r>
</w:p>
</w:tc>
Setting column width to 35 mm = 1984 dxa manually in MS-Word gives:
<w:tbl>
<w:tblPr>
<w:tblW w:w="8898" w:type="dxa"/>
<w:tblBorders>
<w:top w:val="single" w:sz="4" w:space="0" w:color="auto"/>
<w:left w:val="single" w:sz="4" w:space="0" w:color="auto"/>
<w:bottom w:val="single" w:sz="4" w:space="0" w:color="auto"/>
<w:right w:val="single" w:sz="4" w:space="0" w:color="auto"/>
<w:insideH w:val="single" w:sz="4" w:space="0" w:color="auto"/>
<w:insideV w:val="single" w:sz="4" w:space="0" w:color="auto"/>
</w:tblBorders>
<w:tblLook w:val="0000" w:firstRow="0" w:lastRow="0" w:firstColumn="0" w:lastColumn="0" w:noHBand="0" w:noVBand="0"/>
</w:tblPr>
<w:tblGrid>
---> <w:gridCol w:w="1984"/>
<w:gridCol w:w="6914"/>
</w:tblGrid>
<w:tr w:rsidR="000A3B7A" w:rsidRPr="00046723" w:rsidTr="00A24E8D">
<w:tc>
<w:tcPr>
---> <w:tcW w:w="1984" w:type="dxa"/>
<w:shd w:val="clear" w:color="auto" w:fill="auto"/>
</w:tcPr>
<w:p w:rsidR="009442E8" w:rsidRDefault="00877FA9">
<w:bookmarkStart w:id="0" w:name="_GoBack" w:colFirst="0" w:colLast="0"/>
<w:r>
<w:t>Arbeitsaufwand</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
Hence, I set both column width and individual cell widths in python-docx and get:
<w:tbl>
<w:tblPr>
<w:tblW w:w="9288" w:type="dxa"/>
<w:tblBorders>
<w:top w:val="single" w:sz="4" w:space="0" w:color="auto"/>
<w:left w:val="single" w:sz="4" w:space="0" w:color="auto"/>
<w:bottom w:val="single" w:sz="4" w:space="0" w:color="auto"/>
<w:right w:val="single" w:sz="4" w:space="0" w:color="auto"/>
<w:insideH w:val="single" w:sz="4" w:space="0" w:color="auto"/>
<w:insideV w:val="single" w:sz="4" w:space="0" w:color="auto"/>
</w:tblBorders>
<w:tblLook w:val="0000" w:firstRow="0" w:lastRow="0" w:firstColumn="0" w:lastColumn="0" w:noHBand="0" w:noVBand="0"/>
</w:tblPr>
<w:tblGrid>
---> <w:gridCol w:w="1984"/>
<w:gridCol w:w="5778"/>
</w:tblGrid>
<w:tr w:rsidR="000A3B7A" w:rsidRPr="00046723" w:rsidTr="0089115F">
<w:tc>
<w:tcPr>
---> <w:tcW w:w="1984" w:type="dxa"/>
<w:shd w:val="clear" w:color="auto" w:fill="auto"/>
</w:tcPr>
<w:p>
<w:r>
<w:t>Arbeitsaufwand</w:t>
</w:r>
</w:p>
</w:tc>
But MS-Word still shows a column width of 41.6 mm. :-(
What about the table width (w:tblW w:w="9288"
vs. 8898 for Word)?
Maybe Word is maintaining the proportion, but scaling to fit the table width.
I see there's not a Table.width
property, but maybe that's where to look. This code might work for setting that:
tblPr = table._tblPr
tblW = tblPr.xpath('./tblW')[0]
tblW.width = Mm(42) # --whatever the sum of column widths is.
I spent a few hours trying to figure out what I was doing wrong here. At first, I was trying to set the column width, to no avail (page is landscape): block_table.columns[0].width = Inches(0.7) block_table.columns[1].width = Inches(0.7) block_table.columns[2].width = Inches(1.3) block_table.columns[3].width = Inches(7.8) block_table.autofit = False
The header (full code clip later for brevity) would look fine, but after adding data it would go to the columns begin equal width across the page. So I tried setting this after populating the data, same problem.
I then shifted to setting all of the header column cells the proper width: block_table.columns[0].cells[0].width = Inches(0.7) block_table.columns[1].cells[0].width = Inches(0.7) block_table.columns[2].cells[0].width = Inches(1.3) block_table.columns[3].cells[0].width = Inches(7.8) block_table.autofit = False
This also fails, in the same manner, either before or after populating data within the table.
The only way to get it to work was as suggested above to where you need to go to each column and then set each row's cell in that column to the desired width, otherwise it never works. I can see it updating the objects width in the debugger, so I know its happening to a degree.
This leads me to believe there might be a couple of issues here:
Not sure if this helps, but the library is providing a lot of value for me right now and I felt it was appropriate to share some observations. Hopefully useful.
# populate header row --------
heading_cells = block_table.rows[0].cells
heading_cells[0].text = 'ID'
heading_cells[1].text = 'FIXED'
heading_cells[2].text = 'WORKAROUND'
heading_cells[3].text = 'TITLE'
for data in example_data:
cell_row = block_table.add_row().cells
cell_row[0].text = data.get("ID")
cell_row[1].text = data.get("FIXED")
cell_row[2].text = data.get("WORKAROUND")
cell_row[3].text = data.get("TITLE")
self.setColumnWidth(block_table, 0, 0.7)
self.setColumnWidth(block_table, 1, 0.7)
self.setColumnWidth(block_table, 2, 1.3)
self.setColumnWidth(block_table, 3, 7.8)
Please add the recommendation to set cell rather than column widths to the documentation. I too wasted a lot of time constructing examples to figure out what was going wrong until I went looking is these pages.
Hi,
I have following table in my document;
If I open the document in Apple Pages, all column widths are correct but not on MS Word. Am I missing something?