Page 1 of 1

tabl caption and border issue docx4j 3.0.0

PostPosted: Sat Feb 01, 2014 7:11 am
by davidrlee
Hey guys, I'm having an issue with getting the table caption and border to output in PDF. I'm using docx4j 3.0.0 but I also had the same issue with 2.8.1.

I have a xhtml fragment generated by TinyMCE. I do some processing to get it the way docx4j wants it, and convert it to openXML using XHTMLImporterImpl.
I use the marshaller to get the docx format working and Docx4j.toPDF for the pdf format.
It works for most cases, italics, underline, bold, alignment, images, etc.

When it comes to table caption and border, it works in the docx format, but not the PDF format. It simply excludes the table with these properties. I think xhtml -> openXML is working properly, but the Docx4j.toPDF is not supporting these properties or something. I tried searching the web with no luck. I was wondering if someone already knew about this.

The error I get is
java.lang.StringIndexOutOfBoundsException: String index out of range: 9
at java.lang.String.substring(String.java:1907)
at org.apache.fop.fo.expr.PropertyTokenizer.nextColor(PropertyTokenizer.java:239)
at org.apache.fop.fo.expr.PropertyTokenizer.next(PropertyTokenizer.java:175)
at org.apache.fop.fo.expr.PropertyParser.parseProperty(PropertyParser.java:118)
at org.apache.fop.fo.expr.PropertyParser.parse(PropertyParser.java:91)
at org.apache.fop.fo.properties.PropertyMaker.make(PropertyMaker.java:438)
at org.apache.fop.fo.PropertyList.convertAttributeToProperty(PropertyList.java:413)
at org.apache.fop.fo.PropertyList.addAttributesToList(PropertyList.java:321)
at org.apache.fop.fo.FObj.processNode(FObj.java:122)
at org.apache.fop.fo.flow.table.TableFObj.processNode(TableFObj.java:232)
...
Caused by: org.docx4j.openpackaging.exceptions.Docx4JException: Exception exporting package
at org.docx4j.convert.out.common.AbstractExporter.export(AbstractExporter.java:79)
at org.docx4j.Docx4J.toFO(Docx4J.java:467)
at org.docx4j.Docx4J.toPDF(Docx4J.java:477)


The openXML looks like this for the table

<w:tbl>
<w:tblPr>
<w:tblW w:w="0" w:type="auto"/>
<w:tblCellSpacing w:w="20" w:type="dxa"/>
<w:tblInd w:w="115" w:type="dxa"/>
<w:tblBorders>
<w:top w:val="inset" w:color="#000000" w:sz="8"/>
<w:left w:val="inset" w:color="#000000" w:sz="8"/>
<w:bottom w:val="inset" w:color="#000000" w:sz="8"/>
<w:right w:val="inset" w:color="#000000" w:sz="8"/>
<w:insideH w:val="none"/>
<w:insideV w:val="none"/>
</w:tblBorders>
</w:tblPr>
<w:tblGrid>
<w:gridCol w:w="1045"/>
<w:gridCol w:w="903"/>
</w:tblGrid>
<w:tr>
<w:tc>
<w:tcPr>
<w:tcW w:w="1045" w:type="dxa"/>
<w:tcBorders>
<w:top w:val="outset" w:color="#000000" w:sz="8"/>
<w:left w:val="outset" w:color="#000000" w:sz="8"/>
<w:bottom w:val="outset" w:color="#000000" w:sz="8"/>
<w:right w:val="outset" w:color="#000000" w:sz="8"/>
</w:tcBorders>
</w:tcPr>
<w:p>
<w:pPr>
<w:spacing w:after="0"/>
<w:ind w:left="0"/>
<w:jc w:val="left"/>
</w:pPr>
<w:r>
<w:rPr>
<w:b w:val="false"/>
<w:i w:val="false"/>
<w:color w:val="000000"/>
<w:sz w:val="22"/>
</w:rPr>
<w:t>Col 1</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="903" w:type="dxa"/>
<w:tcBorders>
<w:top w:val="outset" w:color="#000000" w:sz="8"/>
<w:left w:val="outset" w:color="#000000" w:sz="8"/>
<w:bottom w:val="outset" w:color="#000000" w:sz="8"/>
<w:right w:val="outset" w:color="#000000" w:sz="8"/>
</w:tcBorders>
</w:tcPr>
<w:p>
<w:pPr>
<w:spacing w:after="0"/>
<w:ind w:left="0"/>
<w:jc w:val="left"/>
</w:pPr>
<w:r>
<w:rPr>
<w:b w:val="false"/>
<w:i w:val="false"/>
<w:color w:val="000000"/>
<w:sz w:val="22"/>
</w:rPr>
<w:t>Col2</w:t>
</w:r>
</w:p>
</w:tc>
</w:tr>
<w:tr>
<w:tc>
<w:tcPr>
<w:tcW w:w="1045" w:type="dxa"/>
<w:tcBorders>
<w:top w:val="outset" w:color="#000000" w:sz="8"/>
<w:left w:val="outset" w:color="#000000" w:sz="8"/>
<w:bottom w:val="outset" w:color="#000000" w:sz="8"/>
<w:right w:val="outset" w:color="#000000" w:sz="8"/>
</w:tcBorders>
</w:tcPr>
<w:p>
<w:pPr>
<w:spacing w:after="0"/>
<w:ind w:left="0"/>
<w:jc w:val="left"/>
</w:pPr>
<w:r>
<w:rPr>
<w:b w:val="false"/>
<w:i w:val="false"/>
<w:color w:val="000000"/>
<w:sz w:val="22"/>
</w:rPr>
<w:t>Row1</w:t>
</w:r>
</w:p>
</w:tc>
<w:tc>
<w:tcPr>
<w:tcW w:w="903" w:type="dxa"/>
<w:tcBorders>
<w:top w:val="outset" w:color="#000000" w:sz="8"/>
<w:left w:val="outset" w:color="#000000" w:sz="8"/>
<w:bottom w:val="outset" w:color="#000000" w:sz="8"/>
<w:right w:val="outset" w:color="#000000" w:sz="8"/>
</w:tcBorders>
</w:tcPr>
<w:p>
<w:pPr>
<w:spacing w:after="0"/>
<w:ind w:left="0"/>
<w:jc w:val="left"/>
</w:pPr>
<w:r>
<w:rPr>
<w:b w:val="false"/>
<w:i w:val="false"/>
<w:color w:val="000000"/>
<w:sz w:val="22"/>
</w:rPr>
<w:t>table</w:t>
</w:r>
</w:p>
</w:tc>
</w:tr>
</w:tbl>

Re: tabl caption and border issue docx4j 3.0.0

PostPosted: Sat Feb 01, 2014 7:18 am
by davidrlee
Hmm It looks like the color should be 000000 not #000000

I debugged that line and I'm getting ##000000 and tries to substring from 0 to 9

Re: tabl caption and border issue docx4j 3.0.0

PostPosted: Sat Feb 01, 2014 7:50 am
by davidrlee
XHTMLImporterImpl.java:1440
private CTBorder copyBorderStyle(Box box, String side, boolean keepNone) {
...
borderColor is something like #000000
...
color is borderColor.toString so it's #000000, but createBorderStyle is expecting 000000
...
return createBorderStyle( stBorder, color, BigInteger.valueOf( Math.round(width) ) );
}


My xhtml just has <table border="1">, I don't think I'm setting the color. Is this a bug?

Re: tabl caption and border issue docx4j 3.0.0

PostPosted: Sat Feb 01, 2014 9:17 am
by jason
Just pushed the fix for https://github.com/plutext/docx4j/issues/101 and this.. https://github.com/plutext/docx4j-Impor ... 86b583047d

It will be in 3.0.1, due shortly.

Re: tabl caption and border issue docx4j 3.0.0

PostPosted: Tue Feb 04, 2014 4:24 am
by davidrlee
Oh wow! I saw the fix before I saw this message. Thank you for the quick turnaround.

I tested this locally, and the border issue seems to be fixed.
I'm still having trouble with the table caption, I'm trying to debug it now but if you have any ideas, please let me know.

html looks like
Code: Select all
<table border="1" cellpadding="5"><caption>test caption</caption>


wml looks like
Code: Select all
<w:tbl>
            <w:tblPr/>
            <w:tr>
                <w:tc>
                    <w:p>
                        <w:pPr>
                            <w:spacing w:after="0"/>
                            <w:ind w:left="0"/>
                            <w:jc w:val="center"/>
                        </w:pPr>
                        <w:r>
                            <w:rPr>
                                <w:b w:val="false"/>
                                <w:i w:val="false"/>
                                <w:color w:val="000000"/>
                                <w:sz w:val="22"/>
                            </w:rPr>
                            <w:t>test caption</w:t>
                        </w:r>
                    </w:p>
                </w:tc>
            </w:tr>
            <w:tbl>
                <w:tblPr>
                    <w:tblW w:w="0" w:type="auto"/>
                    <w:tblCellSpacing w:w="20" w:type="dxa"/>
                    <w:tblInd w:w="115" w:type="dxa"/>
                    <w:tblBorders>
                        <w:top w:val="inset" w:color="000000" w:sz="8"/>
                        <w:left w:val="inset" w:color="000000" w:sz="8"/>
                        <w:bottom w:val="inset" w:color="000000" w:sz="8"/>
                        <w:right w:val="inset" w:color="000000" w:sz="8"/>
                        <w:insideH w:val="none"/>
                        <w:insideV w:val="none"/>
                    </w:tblBorders>
                </w:tblPr>

Re: tabl caption and border issue docx4j 3.0.0

PostPosted: Tue Feb 04, 2014 6:32 am
by davidrlee
The error I get is.. basically table.getEffectiveTableStyle().getTblPr() seems to be null when I add a table caption.
I tried checking for null, and I was able to get the caption to display but not the table itself.

I read a little bit about the wml, it looks like there's different ways of outputting the table caption. Maybe the generated wml is incorrect?
I don't think this is a small issue that I could solve so I'm going to give up and just use regex to parse out the caption text and put it before the table.

Code: Select all
java.lang.NullPointerException
   at org.docx4j.convert.out.common.writer.AbstractTableWriter.createCellProperties(AbstractTableWriter.java:388)
   at org.docx4j.convert.out.common.writer.AbstractTableWriter.toNode(AbstractTableWriter.java:209)
   at org.docx4j.convert.out.common.writer.AbstractTableWriter.toNode(AbstractTableWriter.java:183)
   at org.docx4j.convert.out.common.AbstractWriterRegistry.toNode(AbstractWriterRegistry.java:138)
   at org.docx4j.convert.out.common.AbstractWriterRegistry.toNode(AbstractWriterRegistry.java:109)
   at org.docx4j.convert.out.common.XsltCommonFunctions.toNode(XsltCommonFunctions.java:130)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
   at java.lang.reflect.Method.invoke(Method.java:606)
   at org.apache.xalan.extensions.ExtensionHandlerJavaPackage.callFunction(ExtensionHandlerJavaPackage.java:343)
   at org.apache.xalan.extensions.ExtensionHandlerJavaPackage.callFunction(ExtensionHandlerJavaPackage.java:440)
at org.apache.xalan.extensions.ExtensionsTable.extFunction(ExtensionsTable.java:222)
   at org.apache.xalan.transformer.TransformerImpl.extFunction(TransformerImpl.java:473)
   at org.apache.xpath.functions.FuncExtFunction.execute(FuncExtFunction.java:208)
   at org.apache.xpath.XPath.execute(XPath.java:337)
   at org.apache.xalan.templates.ElemCopyOf.execute(ElemCopyOf.java:134)
   at org.apache.xalan.templates.ElemApplyTemplates.transformSelectedNodes(ElemApplyTemplates.java:395)
   at org.apache.xalan.templates.ElemApplyTemplates.execute(ElemApplyTemplates.java:178)
   at org.apache.xalan.transformer.TransformerImpl.executeChildTemplates(TransformerImpl.java:2400)
   at org.apache.xalan.templates.ElemLiteralResult.execute(ElemLiteralResult.java:1376)
   at org.apache.xalan.transformer.TransformerImpl.executeChildTemplates(TransformerImpl.java:2400)
   at org.apache.xalan.templates.ElemLiteralResult.execute(ElemLiteralResult.java:1376)
   at org.apache.xalan.templates.ElemApplyTemplates.transformSelectedNodes(ElemApplyTemplates.java:395)
   at org.apache.xalan.templates.ElemApplyTemplates.execute(ElemApplyTemplates.java:178)
   at org.apache.xalan.transformer.TransformerImpl.executeChildTemplates(TransformerImpl.java:2400)
   at org.apache.xalan.templates.ElemLiteralResult.execute(ElemLiteralResult.java:1376)
   at org.apache.xalan.templates.ElemApplyTemplates.transformSelectedNodes(ElemApplyTemplates.java:395)
   at org.apache.xalan.templates.ElemApplyTemplates.execute(ElemApplyTemplates.java:178)
   at org.apache.xalan.transformer.TransformerImpl.executeChildTemplates(TransformerImpl.java:2400)
   at org.apache.xalan.transformer.TransformerImpl.applyTemplateToNode(TransformerImpl.java:2270)
   at org.apache.xalan.transformer.TransformerImpl.transformNode(TransformerImpl.java:1356)
   at org.apache.xalan.transformer.TransformerImpl.transform(TransformerImpl.java:709)
   at org.apache.xalan.transformer.TransformerImpl.transform(TransformerImpl.java:1273)
   at org.apache.xalan.transformer.TransformerImpl.transform(TransformerImpl.java:1251)
   at org.docx4j.XmlUtils.transform(XmlUtils.java:941)
   at org.docx4j.XmlUtils.transform(XmlUtils.java:832)
   at org.docx4j.convert.out.common.AbstractXsltExporterDelegate.process(AbstractXsltExporterDelegate.java:59)
   at org.docx4j.convert.out.common.AbstractWmlExporter.process(AbstractWmlExporter.java:63)
   at org.docx4j.convert.out.common.AbstractWmlExporter.process(AbstractWmlExporter.java:32)
   at org.docx4j.convert.out.common.AbstractExporter.export(AbstractExporter.java:71)
   at org.docx4j.Docx4J.toFO(Docx4J.java:467)
   at org.docx4j.Docx4J.toPDF(Docx4J.java:477)