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.
Related
Hi recently I'm working on a project and one of the reporting module is using iText 2.0.8 version library. Everything work fine until the number of data became huge (around 50,000+ of row). I really need suggestion from every expert on Stackoverflow to improve my code.
My code logic: I wrote HTML code with all data contained inside. After the full HTML code is done, it will store into a variable called as "content", then I'll convert the "content" variable into IElement list and perform a for loop to add into the document. I realise this loop is causing a bad performance (CPU usage is high) and the report is generating very slow (even caused connection timeout).
The following the part of code that caused a very high CPU usage for Java process.
//The **content** String variable is contain the HTML code of the report
//(From <head> to <body> with <table> as the main content to structure the data row).
//I didnt include here because the code is huge.
String PDFFileName = "123.pdf";
PdfDocument pdf = new PdfDocument(new PdfWriter(new FileOutputStream(PDFFileName)));
Document document = new Document(pdf);
List<IElement> dataElements = HtmlConverter.convertToElements(content.toString(), converterProperties);
for (IElement element : dataElements) {
if (element instanceof IBlockElement) {
document.add((IBlockElement) element);
}
}
I know the loop is the issue, but I don't any other way is better and efficient for my case, hope someone can help me on this! Thank you. Please comment below if need extra information (Sorry cant really include all the code since it's very huge).
Specification: itext 2.0.8, Java 8.0, HTML, CSS.
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).
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.
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
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.