maxXwpfNum = numbering.getNums().stream().max(Comparator.comparing(o -> o.getCTNum().getNumId()));
+ this.maxNum = maxXwpfNum.map(xwpfNum -> xwpfNum.getCTNum().getNumId().intValue()).orElse(0);
+
} catch (Exception e) {
new DocxGenerationException(e.getClass().getSimpleName() + " Copying numbering definitions from template doc: " + e.getMessage(), e);
}
@@ -3114,5 +3176,52 @@ else if ("jpeg".equals(imgExtension) ||
return format;
}
+ /**
+ *
+ * Add table grid (w:tblGrid) and grid columns (w:gridCol) based on table column definitions.
+ *
+ *
+ * @param table XWPF table
+ * @param colDefs table column definitions
+ */
+ public static void addTableGridWithColumnsIfNeeded(XWPFTable table, TableColumnDefinitions colDefs) {
+ CTTblGrid tblGrid = table.getCTTbl().getTblGrid();
+ if (tblGrid == null) {
+ tblGrid = table.getCTTbl().addNewTblGrid();
+ for (TableColumnDefinition colDef : colDefs.getColumnDefinitions()) {
+ String specifiedWidth = colDef.getSpecifiedWidth();
+ CTTblGridCol gridCol = tblGrid.addNewGridCol();
+ BigInteger gridColWidth;
+ // logic below has been copied from XWPFTable.setWidthValue
+ if (specifiedWidth.matches(XWPFTable.REGEX_PERCENTAGE)) {
+ String numberPart = specifiedWidth.substring(0, specifiedWidth.length() - 1);
+ double percentage = Double.parseDouble(numberPart) * 50;
+ long intValue = Math.round(percentage);
+ gridColWidth = BigInteger.valueOf(intValue);
+ } else if (specifiedWidth.matches("auto")) {
+ gridColWidth = BigInteger.ZERO;
+ } else {
+ gridColWidth = new BigInteger(specifiedWidth);
+ }
+ gridCol.setW(gridColWidth);
+ }
+ }
+ }
+
+ /**
+ *
+ * Set table width to 100% and change width type if needed for correct displaying in the both MS Word and LibreOffice
+ *
+ *
+ * @param table XWPF table
+ */
+ public static void setDefaultTableWidthIfNeeded(XWPFTable table) {
+ if (table.getWidthType() == TableWidthType.AUTO && table.getWidth() == 0) {
+ table.setWidth(DEFAULT_TABLE_WIDTH);
+ } else if (table.getWidthType() == TableWidthType.NIL) {
+ table.setWidthType(TableWidthType.PCT);
+ table.setWidth(DEFAULT_TABLE_WIDTH);
+ }
+ }
}
diff --git a/src/main/xsl/html2docx/baseProcessing.xsl b/src/main/xsl/html2docx/baseProcessing.xsl
index 22de534..c1ba5e7 100644
--- a/src/main/xsl/html2docx/baseProcessing.xsl
+++ b/src/main/xsl/html2docx/baseProcessing.xsl
@@ -141,10 +141,8 @@
-
-
-
-
+
+
diff --git a/src/main/xsl/html2docx/get-style-name.xsl b/src/main/xsl/html2docx/get-style-name.xsl
index 54be602..2fa7f1b 100644
--- a/src/main/xsl/html2docx/get-style-name.xsl
+++ b/src/main/xsl/html2docx/get-style-name.xsl
@@ -87,7 +87,14 @@
-
+
+
+
+
+
+
+
+
diff --git a/src/test/java/org/wordinator/xml2docx/TestDocxGenerator.java b/src/test/java/org/wordinator/xml2docx/TestDocxGenerator.java
index c21a579..7cecbb5 100644
--- a/src/test/java/org/wordinator/xml2docx/TestDocxGenerator.java
+++ b/src/test/java/org/wordinator/xml2docx/TestDocxGenerator.java
@@ -10,6 +10,7 @@
import org.apache.poi.xwpf.usermodel.BodyElementType;
import org.apache.poi.xwpf.usermodel.IBodyElement;
import org.apache.poi.xwpf.usermodel.IRunElement;
+import org.apache.poi.xwpf.usermodel.TableWidthType;
import org.apache.poi.xwpf.usermodel.XWPFAbstractNum;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFFooter;
@@ -26,16 +27,22 @@
import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlObject;
import org.junit.Test;
+import org.mockito.Mockito;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBody;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTDocument1;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTFldChar;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTPageMar;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTR;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTSectPr;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTbl;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblGrid;
+import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTTblGridCol;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTText;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STFldCharType;
import org.wordinator.xml2docx.generator.DocxConstants;
import org.wordinator.xml2docx.generator.DocxGenerator;
+import org.wordinator.xml2docx.generator.MeasurementException;
+import org.wordinator.xml2docx.generator.TableColumnDefinitions;
import junit.framework.TestCase;
@@ -515,6 +522,98 @@ public void testNestedTableWidth() throws Exception {
assertEquals(BodyElementType.TABLE, elem.getElementType());
}
+ @Test
+ public void testAddTableGridWithColumnsIfNeeded__should_create_table_grid_width_in_percentages() throws MeasurementException {
+ // GIVEN
+ XWPFTable table = Mockito.mock(XWPFTable.class);
+ CTTbl ctTbl = Mockito.mock(CTTbl.class);
+ CTTblGrid ctTblGrid = Mockito.mock(CTTblGrid.class);
+ CTTblGridCol col1 = Mockito.mock(CTTblGridCol.class);
+ CTTblGridCol col2 = Mockito.mock(CTTblGridCol.class);
+ Mockito.when(table.getCTTbl()).thenReturn(ctTbl);
+ Mockito.when(ctTbl.addNewTblGrid()).thenReturn(ctTblGrid);
+ Mockito.when(ctTblGrid.addNewGridCol()).thenReturn(col1, col2);
+
+ TableColumnDefinitions colDefs = new TableColumnDefinitions();
+ final int dotsPerInch = 72;
+ colDefs.newColumnDef().setWidth("30%", dotsPerInch);
+ colDefs.newColumnDef().setWidth("70%", dotsPerInch);
+
+ // WHEN
+ DocxGenerator.addTableGridWithColumnsIfNeeded(table, colDefs);
+
+ // THEN
+ Mockito.verify(col1).setW(BigInteger.valueOf(1500));
+ Mockito.verify(col2).setW(BigInteger.valueOf(3500));
+ }
+
+ @Test
+ public void testAddTableGridWithColumnsIfNeeded__should_create_table_grid_auto_width() {
+ // GIVEN
+ XWPFTable table = Mockito.mock(XWPFTable.class);
+ CTTbl ctTbl = Mockito.mock(CTTbl.class);
+ CTTblGrid ctTblGrid = Mockito.mock(CTTblGrid.class);
+ CTTblGridCol col1 = Mockito.mock(CTTblGridCol.class);
+ CTTblGridCol col2 = Mockito.mock(CTTblGridCol.class);
+ Mockito.when(table.getCTTbl()).thenReturn(ctTbl);
+ Mockito.when(ctTbl.addNewTblGrid()).thenReturn(ctTblGrid);
+ Mockito.when(ctTblGrid.addNewGridCol()).thenReturn(col1, col2);
+
+ TableColumnDefinitions colDefs = new TableColumnDefinitions();
+ colDefs.newColumnDef().setWidthAuto();
+ colDefs.newColumnDef().setWidthAuto();
+
+ // WHEN
+ DocxGenerator.addTableGridWithColumnsIfNeeded(table, colDefs);
+
+ // THEN
+ Mockito.verify(col1).setW(BigInteger.ZERO);
+ Mockito.verify(col2).setW(BigInteger.ZERO);
+ }
+
+ @Test
+ public void testAddTableGridWithColumnsIfNeeded__should_create_table_grid_width_in_ints() throws MeasurementException {
+ // GIVEN
+ XWPFTable table = Mockito.mock(XWPFTable.class);
+ CTTbl ctTbl = Mockito.mock(CTTbl.class);
+ CTTblGrid ctTblGrid = Mockito.mock(CTTblGrid.class);
+ CTTblGridCol col1 = Mockito.mock(CTTblGridCol.class);
+ CTTblGridCol col2 = Mockito.mock(CTTblGridCol.class);
+ Mockito.when(table.getCTTbl()).thenReturn(ctTbl);
+ Mockito.when(ctTbl.addNewTblGrid()).thenReturn(ctTblGrid);
+ Mockito.when(ctTblGrid.addNewGridCol()).thenReturn(col1, col2);
+
+ TableColumnDefinitions colDefs = new TableColumnDefinitions();
+ final int dotsPerInch = 72;
+ colDefs.newColumnDef().setWidth("30", dotsPerInch);
+ colDefs.newColumnDef().setWidth("70", dotsPerInch);
+
+ // WHEN
+ DocxGenerator.addTableGridWithColumnsIfNeeded(table, colDefs);
+
+ // THEN
+ Mockito.verify(col1).setW(BigInteger.valueOf(30));
+ Mockito.verify(col2).setW(BigInteger.valueOf(70));
+ }
+
+ @Test
+ public void testSetDefaultTableWidthIfNeeded__should_set_100_percentages_width_for_auto_width_type() {
+ XWPFTable table = Mockito.mock(XWPFTable.class);
+ Mockito.when(table.getWidthType()).thenReturn(TableWidthType.AUTO);
+ Mockito.when(table.getWidth()).thenReturn(0);
+ DocxGenerator.setDefaultTableWidthIfNeeded(table);
+ Mockito.verify(table).setWidth("100%");
+ }
+
+ @Test
+ public void testSetDefaultTableWidthIfNeeded__should_set_100_percentages_width_and_pct_type_for_nil_width_type() {
+ XWPFTable table = Mockito.mock(XWPFTable.class);
+ Mockito.when(table.getWidthType()).thenReturn(TableWidthType.NIL);
+ DocxGenerator.setDefaultTableWidthIfNeeded(table);
+ Mockito.verify(table).setWidthType(TableWidthType.PCT);
+ Mockito.verify(table).setWidth("100%");
+ }
+
// ===== INTERNAL UTILITIES
private XWPFDocument convert(String infile, String outfile) throws Exception {