Internal cttable grid null using apache poi - java

We are using poi to render into a word document and then convert to pdf. The PDF converter is failing - and when I debugged into it - what I found is that it's using calling the internal bean functions and the "tblGrid" - which it's using the apache XWPFTableUtil to call computeColWidths to work out the table size, and that throws a null reference exception because getTblGrid returns null.
Basically the code to reproduce it is easy:
output = new XWPFDocument( {stream to template} );
XWPFTable table = output.createTable();
Ensure.notNull( table.getCTTbl().getTblGrid() )
now - obviously I can't easily change the pdf library - so what I want is to figure out how to make that call not return null - it looks like there should be a function "calculategrid" or something? I've searched, but can't find anything.
Anyone know what I'm missing? (Btw it happens if I add rows and columns to the table, it's not as simple as the fact that it's just empty - I'm just using this as the simplest possible example).

Related

Itext hyphenation in Table cells

I´m creating a table using iText.
But the output looks really bad, because of the hyphenation, which seems not to be done properly.
I allready read this question How to hyphenate text?
and this example http://itextpdf.com/sandbox/tables/HyphenationExample
I tried the example in eclipse after i added the itext_hyph_xml.jar to my class path. No error is thrown when i run the code, but the lines
Hyphenator h = new Hyphenator("de", "DE", 2, 2);
Hyphenation s = h.hyphenate("Leistungsscheinziffer");
System.out.println(s);
print null to the console instead of "Lei-stungs-schein-zif-fer" or something similar as i expected.
I tried playing with the parameters in
chunk.setHyphenation(new HyphenationAuto("de", "DE", 2,2));
but the output in the document never differes even slightly.
The code i´m trying to get to work looks kind of like this by the way:
for(String s: interest){
Chunk chunk = new Chunk(s,FONT[0]);
chunk.setHyphenation(new HyphenationAuto("de", "DE", 2,3));
table.addCell(new Phrase(chunk));
}
Ok I figured it out on my own now.
And because i couldn´t find the answer on the internet i thought i will share it here so anyone who might have the same error in the future wouldn´t need a week to figure it out.
It seems that in the class Hyphenator the defaultHyphLocation is set like this:
private static final String defaultHyphLocation = "com/itextpdf/text/pdf/hyphenation/hyph/";
But the structure of itext_hyph.jar looks like this:
com.lowagie.text.pdf.hyphenation.hyph
Obviously loading a hyph file from the jar will surely fail, since the path used by Hyphenator can not be found. I actually thought this would cause an error but it seems simply null is returned when the loading of the hyph file fails.
Calling Hyphenator.setHyphenDir("com/lowagie/text/pdf/hyphenation/hyph/"); however wouldn´t change a thing as one would think, since it changes the wrong string variable.
The only thing i could think of to solve this problem was to recreate the itext_hyph.jar according to the path given in Hyphenator and that acctually fixed it. Hyphenation is now working.

SXSSF generated corrupted report in Z/OS on applying cell Style

I am trying to execute a program in Z-OS machine to write an Excel report.
Due to size of the report, we are using SXSSFWorkbook to write the report.
One of the cells in the report is grey in color. So I have to apply Color to that cell.
I used the following code to set the color.
XSSFCellStyle cellStyle = (XSSFCellStyle) wb.createCellStyle();
XSSFColor myColor = new XSSFColor(DatatypeConverter
.parseHexBinary("FFBFBFBF")); //also tried the java.awt.Color
cellStyle.setFillForegroundColor(myColor);
cell.setCellStyle(cellStyle);
But for the report generated, this cell is dark in color.
Out of curiosity, I checked the Styles.xml inside the Excel document.
The following is what I found.
<fill><patternFill patternType="solid"><fgColor rgb="ããâãâãâã"/></patternFill></fill>
I tried to generate the same report in a Windows machine, and it gave me correct result.
<fill><patternFill patternType="solid"><fgColor rgb="FFBFBFBF"/></patternFill>
Can anyone help me to resolve this issue?
----------------------EDITED---------------------------
I have reported a bug for this.
https://issues.apache.org/bugzilla/show_bug.cgi?id=56683
To debug this, i need to see the code for CT classes in POI.
I followed the instructions given in following link to generate the code.
http://poi.apache.org/faq.html#faq-N1012A
1) I am not able to find ' ooxml-schemas-src jar'.
2) I checkedout POI code and ANT build it.
None of the approch gave me the code for CT classes.
let me know if someone have done it before.
---------------EDITED----------------------------
Not sure if the following update will fix it. need to try it out.
Updated writeTo() method of 'org.apache.poi.xssf.model.StylesTable'.
Change: Added the following line
'DEFAULT_XML_OPTIONS.setCharacterEncoding("UTF-8");'
/**
* Write this table out as XML.
*
* #param out The stream to write to.
* #throws IOException if an error occurs while writing.
*/
public void writeTo(OutputStream out) throws IOException {
//Setting default encoding to UTF-8
DEFAULT_XML_OPTIONS.setCharacterEncoding("UTF-8");
XmlOptions options = new XmlOptions(DEFAULT_XML_OPTIONS);
Since i dont have control over the z/os server, i have to wait till it get tested.
In the mean time, please let me know your thoughts on the same.
This is resolved now.
Please see the bug page for details.
https://issues.apache.org/bugzilla/show_bug.cgi?id=56683

Can't use Row Data Resulted from Scripted DataSet

Performing a test with BIRT I was able to create a report and render it in PDF, but unfortunatelly I'm not getting the expected result.
For my DataSource I created a Scripted DataSource and no code was needed in there (as far as I could see the documentation to achieve what I'm trying to do).
For my DataSet I create a Scripted DataSet using my Scripted DataSource as source. In there I defined the script for open like:
importPackage(Packages.org.springframework.context);
importPackage(Packages.org.springframework.web.context.support);
var sc = reportContext.getHttpServletRequest().getSession().getServletContext();
var spring = WebApplicationContextUtils.getWebApplicationContext(sc);
myPojo = spring.getBean("myDao").findById(params["pojoId"]);
And script for fetch like:
if(myPojo != null){
row["title"] = myPojo.getTitle();
myPojo = null;
return true;
}
return false;
As the population of row will be done on runtime, I wasn't able to automatically get the DataSet columns, so I created one with the following configuration: name: columnTitle (as this is the name used to populated row object in fetch code).
Afterwards I edited the layout of my report and added the column to my layout.
I was able to confirm that spring.getBean("myDao").findById(params["pojoId"]); is executed. But my rendered report is not showing the title. If I double click on my column label on report layout I can see there that expression is dataSetRow["columnTitle"] is it right? Even I'm using row in my fetch script? What am I missing here?
Well, what is conctractVersion?
It is obviously not initialized in the open event.
Should this read myPojo.contractVersion or perhaps myPojo.getContractVersion()?
Another point: Is the DS with the column "columnTitle" bound to the layout?
You should also run your report as HTML or in the previewer to check for script errors.
Unfortunately, these are silently ignored when generating the report as PDF...
The problem was the use of batik twice (two different versions), one dependency for BIRT and other for DOCX4J.
The issue is quite difficult to identify because there is no log output rendering PDF files.
Rendering HTML I could see an error message which I could investigate and find the problem.
For my case I could remove the DocX4j from maven POM.

iText PDF Table error using writeSelectedRows

I have the next error.
I'm trying to create a PDF using iText, with an specific format. I opted to use tables for each section of the page, because the format that I need to do have tables. All right, I already did everything, I create the tables and adding it with the doc.add(table) method, this worked fine, but I needed to set the tables into an specific position. So I opted to use table.writeSelectedRows() method, and this worked fine.
And here comes the error, this is my code:
table_SectionTwo.addCell(cell_White);
table_SectionTwo.addCell(cell_White);
table_SectionTwo.addCell(p);
table_SectionTwo.addCell(cell_OrderDate);
table_SectionTwo.addCell(cell_CustomerOrderDate);
table_SectionTwo.addCell(cell_OrderNumberSection);
float[] columnWidths = new float[] {38f, 105f, 90f};
table_SectionTwo.setTotalWidth(columnWidths);
table_SectionTwo.setLockedWidth(true);
table_SectionTwo.completeRow();
table_SectionTwo.writeSelectedRows(0, -1, 260f, 770f, super.getPdfWriter().getDirectContent());
doc.add(table_SectionTwo);
As you can see, if I execute this code, this will add the same table 2 times
the problem is when I remove doc.add(table), I do this only for add one table into an specific position using table.writeSelectedRows(). This is how my code remains:
table_SectionTwo.writeSelectedRows(0, -1, 260f, 770f, super.getPdfWriter().getDirectContent());
//super.addTable(table_SectionTwo);
I commented doc.add(table).
And this should write only one table. But this doesn't work. When I do this throws:
ExceptionConverter: java.io.IOException: The document has no pages.
at com.itextpdf.text.pdf.PdfPages.writePageTree(PdfPages.java:113)
at com.itextpdf.text.pdf.PdfWriter.close(PdfWriter.java:1217)
at com.itextpdf.text.pdf.PdfDocument.close(PdfDocument.java:777)
at com.itextpdf.text.Document.close(Document.java:398)
at PDFConstructor.CloseDocument(PDFConstructor.java:85)
at InvoicePDF.CloseDocument(InvoicePDF.java:58)
at Demo.main(Demo.java:72)
The curious thing is when I comment the doc.add(table) this doesn't work, and when I comment the table.writeSelectedRows() the doc.add(table) works fine.
This error occurs only when I have doc.add(table) commented and table.writeSelectedRows() uncommented.
Please help me..
Although you don't give sufficient information in your question, I think the problem is caused by the fact that you don't define the width of the table.
Do this test: ask the table for its total height. If iText returns 0, then you forgot to define the width of the table; if it doesn't return 0, then iText knows the width either because you defined it explicitly, or because you used document.add(table), which calculated the dimensions of the table based on the page metrics of the document object.
If something else is at play, you'll have to provide more info.
What i understand from your question that you want to write specific rows to document but at a specified position.If this is correct super.getPdfWriter().getDirectContent()) is that necessary?i don't think so.To analyse this part i need your whole code snippet or a demo version of this code which explain the same.
2nd:Internally itext also use PdfContentByte to write PdfPTable using PdfPRow & also Remember according to the author(Bruno) itext is built on Builder Pattern.If previous lines have no meaning to you skip it.
You currently adding content to table even before its all required property is set.
table_SectionTwo.addCell(cell_White);
table_SectionTwo.addCell(cell_White);
table_SectionTwo.addCell(p);
table_SectionTwo.addCell(cell_OrderDate);
table_SectionTwo.addCell(cell_CustomerOrderDate);
table_SectionTwo.addCell(cell_OrderNumberSection);
It will be something like this
float[] columnWidths = new float[] {38f, 105f, 90f};
PdfPTable table_SectionTwo= new PdfPTable(clmnWdthTpHdr);
table_SectionTwo.setTotalWidth(500.0f);
table_SectionTwo.setWidthPercentage(100.0f);
table_SectionTwo.setLockedWidth(true);
3.Don't use super.getPdfWriter().getDirectContent()).As the above code shows me you are using document so i think you must write following code snippet too(Something like this:lol)
PdfWriter pdfWrtr=null;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Document doc= new Document(UtilConstant.pageSizePdf,0,0,0,0);
pdfWrtr=PdfWriter.getInstance(doc,baos);
In try catch use pdfWrtr.getDirectContent(); instead.
These all are based on my code analysis.
Also another point from the exception
ExceptionConverter: java.io.IOException: The document has no pages.
at com.itextpdf.text.pdf.PdfPages.writePageTree(PdfPages.java:113)
...............................
at InvoicePDF.CloseDocument(InvoicePDF.java:58)
at Demo.main(Demo.java:72)
It is a typical error when nothing is added to the document.Maybe an exception is thrown (and ignored) in step 4(according to Itext in Action) andmaybe you are executing step 5 (document.close()) anyway(in spite of the exception in step 4).So please attach Demo.java
if the above is not clear enough to help you.

Is it possible for a column to become a hyperlink using google charts API?

I am using Visualr http://googlevisualr.herokuapp.com/ with Rails and having a good amount of success creating dynamic charts. However, I am wondering if it's possible to allow the user to click on the column in a 'column chart' and be linked to a page? I am happy to know the java version if you aren't familiar with visualr.
Thanks!
It now is available!
There has recently been an update on this issue. Therefore I want to update this SO Q&A.
Resources:
Google Visualr Github Pull Request #39
Google Visualr Github Issue #36
Code example
xxx_controller.rb
#table = GoogleVisualr::Interactive::ColumnChart.new(g, options_g)
#table.add_listener("select", "function(e) {
EventHandler(e, chart, data_table)
}")
And then in a JS file e.g. app/assets/javascripts/application.js:
function EventHandler(e, chart, data) {
var selection = chart.getSelection();
if (selection.length > 0) {
var row = selection[0].row;
var department = data.getValue(row, 0);
alert(department + " | " + row)
}
}
Google Charts (whether you access them directly or via a wrapper gem like Visualr) are simple images, so the straight answer is "No", at least not without doing some work of your own. In order to achieve this you would need to place your own transparent clickable links (or divs or whatever) over the image, in the right place, to correspond to the columns that google generate in the image.
I'd imagine this would be tricky and error prone - it might actually be easier for you to just generate the columns yourself in html and css, using the data you would previously have sent to google to set the height (in %) of the columns. Then, each column would be a seperate html element and could link to whatever you want.
So, more control = more work. As usual :)

Categories

Resources