I wrote the following code in Netbeans editor in Java UI application for generating PDF using itext.
String result="";
Document doc=new Document();
PdfWriter writer=null;
DecimalFormat df=new DecimalFormat("0.00");
try
{
writer=PdfWriter.getInstance(doc, new FileOutputStream(new File("second.pdf")));
doc.addAuthor("abcdefg");
doc.addCreationDate();
doc.addProducer();
doc.addCreator("abcdefg");
doc.addTitle("Invoice for company");
doc.setPageSize(PageSize.A4);
doc.open();
doc.newPage();
doc.add(new Paragraph("new paragraph"));
PdfPTable table = new PdfPTable(1);
PdfPCell cellValue = new PdfPCell(new Phrase("Header 1"));
cellValue.setColspan(1);
table.addCell(cellValue);
doc.add(table);
result= "Successfully created preview.Please check the document";
}
catch(Exception e)
{
result= "Doucment already opened. Please close it";
System.out.println("exception came");
}
finally
{
if(doc!=null)
{
doc.close();
}
if(writer!=null)
{
writer.close();
}
return result;
}
This same piece of code is generating the pdf when I hit the RUN button in NetBeans but if double click the ".JAR" file in the project folder it is not able to add table to the pdf and generating the exception IOException Document has no pages.
There are two interesting things happening here :
1) When I remove the table adding part from my code, it is working very fine in in both the cases. This proves that "build" in netbeans is happening properly.
2) When I add the table part. The exception is generated but it is not executing the catch block and finally block. I am saying this because if catch and finally blocks are executed properly DOCUMENT will be definitely closed properly. But here when I double click the document when my app generated the file, it is showing that the FILE IS ALREADY IN USE AND IT IS DAMAGED FILE. This proves that the catch and finally blocks are not executing.
Related
This is my code:
try {
dozen = magazijn.getFfd().vraagDozenOp();
for (int i = 0; i < dozen.size(); i++) {
PdfWriter.getInstance(doc, new FileOutputStream("Order" + x + ".pdf"));
System.out.println("Writer instance created");
doc.open();
System.out.println("doc open");
Paragraph ordernummer = new Paragraph(order.getOrdernummer());
doc.add(ordernummer);
doc.add( Chunk.NEWLINE );
for (String t : text) {
Paragraph klant = new Paragraph(t);
doc.add(klant);
}
doc.add( Chunk.NEWLINE );
Paragraph datum = new Paragraph (order.getDatum());
doc.add(datum);
doc.add( Chunk.NEWLINE );
artikelen = magazijn.getFfd().vraagArtikelenOp(i);
for (Artikel a : artikelen){
artikelnr.add(a.getArtikelNaam());
}
for (String nr: artikelnr){
Paragraph Artikelnr = new Paragraph(nr);
doc.add(Artikelnr);
}
doc.close();
artikelnr.clear();
x++;
System.out.println("doc closed");
}
} catch (Exception e) {
System.out.println(e);
}
I get this exception: com.itextpdf.text.DocumentException: The document has been closed. You can't add any Elements.
can someone help me fix this so that the other pdf can be created and paragrphs added?
Alright, your intent is not very clear from your code and question so I'm going to operate under the following assumptions:
You are creating a report for each box you're processing
Each report needs to be a separate PDF file
You're getting a DocumentException on the second iteration of the loop, you're trying to add content to a Document that has been closed in the previous iteration via doc.close();. 'doc.close' will finalize the Document and write everything still pending to any linked PdfWriter.
If you wish to create separate pdfs for each box, you need to create a seperate Document in your loop statement as well, since creating a new PdfWriter via PdfWriter.getInstance(doc, new FileOutputStream("Order" + x + ".pdf")); will not create a new Document on its own.
If I'm wrong with assumption 2 and you wish to add everything to a single PDF, move doc.close(); outside of the loop and create only a single PdfWriter
You can try something like this using Apache PDFBox
File outputFile = new File(path);
outputFile.createNewFile();
PDDocument newDoc = new PDDocument();
then create a PDPage and write what you wanna write in that page. After your page is ready, add it to the newDoc and in the end save it and close it
newDoc.save(outputFile);
newDoc.close()
repeat this dozen.size() times and keep changing the file's name in path for every new document.
I am developing an application where i am using POI library to generate .docx files.
By using XWPFTable I am unable to apply table styles. can any one worked on this part? There are no examples and not good documentation out there.
Here is my snippet.
int nRows = 14;
int nCols = 6;
XWPFTable t1 = doc.createTable(nRows, nCols);
t1.setStyleID("Table Grid");
Thanks in advance
I have stumbled on this issue. I have created an empty docx file with all my juicy style available (Heading 1, 2, etc...). I create a XWPFDocument
try {
InputStream resourceAsStream = new FileInputStream("protocol_empty.docx");
document = new XWPFDocument(resourceAsStream);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
then add my paragraph my setting the style ....setStyle("Heading 1");
It works.
Got the answer. I added a template with few styles in it. It worked.
This question helped me
I had trouble identifying the styleId to use. If you make a template and add the table with the style in, export it as a Word XML file then you can look up styleId. So "Light List" for me was actually "LightList" (w:style w:type="table" w:styleId="LightList").
I'm using iText library to create and add data to a PDF.
I want to add some textLines and an image to the PDF more than once until i close the file.
numOfSamples = timeIHitTheButton();
.
.
.
*a loop tha call it the number of times choosen by numOfSamples*
DSM.saveData();
The DataStore (DSM is a DataStore instance) class creates the Document doc.pdf correctly and DSM.addText() and DSM.addPicture() prints correctly three textlines an an image on the file, but only if I press the button just once !!
I WANT TO WRITE THE SAME STRING AND AN IMAGE EVERY TIME I PRESS THE BUTTON (if I press it once i have one sample, if trwice i have two samples etc). IF I PRESS IT JUST ONCE AND I TERMINATE, I GET MY PDF WITH THE STRING AND THE PICTURES, BUT IF I PRESS IT MORE THAN ONCE, I GOT AN UNREADABLE AND DAMAGED PDF FILE. I DON'T KNOW WHY. HOW CAN I CONTINUE WRITIN A PICTURE AND THE STRING CONTINUOSLY UNTIL THE NUMBER OF SAMPLES IS FINISHED?
Here i post some code if useful ("newPic1.jpg" "newPic2.jpg" etc are the stored pictures to add to the PDF togheter with the text.):
public class DataStore{ ....
.
.
.
public DataStore(String Str1, String Str2, String Str3, int numOfSemples)
throws Exception{
document = new Document();
String1 = str1;
String2 = str2;
String3 = str3;
Samples = numOfSemples;
document.open();
}
privatevoid saveData(){
if(!created){
this.createFile();
created=true;
}
this.addText();
this.addPicture();
}
private void createFile(){
try {
OutputStream file = new FileOutputStream(
new File("Doc.pdf"));
PdfWriter.getInstance(document, file);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (DocumentException e) {
e.printStackTrace();
}
}
private void addText(){
try {
if(Samples > 0)
document.open();
document.add(new Paragraph(Double.toString(String1)));
document.add(new Paragraph(Double.toString(String2)));
document.add(new Paragraph(Double.toString(String3)));
} catch (DocumentException e) {
e.printStackTrace();
}
}
private void addPicture(){
try {
Image img = Image.getInstance("NewPic" + Samples + ".jpg");
document.add(img);
} catch (BadElementException bee) {
bee.printStackTrace();
} catch (MalformedURLException mue) {
mue.printStackTrace();
} catch (IOException ioe) {
ioe.printStackTrace();
} catch (DocumentException dee) {
dee.printStackTrace();
}
if(Samples == 0)
document.close();
else Samples--;
}
}
You use iText commands in the wrong order:
Your DataStore constructor creates a new Document and calls its open method (which is too early as there is no writer yet).
Some time later, in the first saveData call, you call createFile which creates the PdfWriter.
In all saveData calls addText is called which for Samples > 0 opens the document again each time (which is ok at the first time but shall not be done multiple times).
Eventually, in the saveData call with Samples == 0 you close the document.
Thus, in essence you do this:
document = new Document();
document.open();
[...]
PdfWriter.getInstance(document, file);
[...]
[for `Samples` times]
document.open();
[add some paragraphs]
[add an image]
[end for]
document.close();
Compare this to how it should be done:
// step 1
Document document = new Document();
// step 2
PdfWriter.getInstance(document, new FileOutputStream(filename));
// step 3
document.open();
// step 4
[add content to the PDF]
// step 5
document.close();
(copied from the HelloWorld.java sample from iText in Action — 2nd Edition)
Only for Samples == 1 you have it about right (the superfluous document.open() in the constructor being ignored as there is no writer yet); for larger values of Samples, though, you open the document multiple times with a writer present which will likely append a PDF start over and over again to the output stream.
Quite likely you can fix the issue by removing all your current document.open() calls (including the if(Samples > 0) in addText()) and add one in createFile() right after PdfWriter.getInstance(document, file).
I am working with PDFBOX and the documentation on it seems sparse so I've come here for some help. I am trying to print out a pdf form that I've created, with fields populated dynamically by eclipse. I can get it to import and print, but when I do print, the fields I've set don't show up (although they do when I save it to HDD). Can someone point me to the settings to set visible when printing? I saw itext had something similar, and I'm hoping that PDFBox does too.
Here is my current code.
PDDocument doc = null;
try{
doc = PDDocument.load("resources/orderForm.pdf");
PDDocumentCatalog docCatalog = doc.getDocumentCatalog();
PDAcroForm acroForm = docCatalog.getAcroForm();
PDField field = acroForm.getField("Orderer");
field.setValue("JohnTest");
} catch (IOException ie){
System.out.println(ie);
}
//doc.addPage(new PDPage());
try{
//doc.save("Empty PDF.pdf");
doc.silentPrint();
//doc.print();
doc.close();
} catch (Exception io){
System.out.println(io);
}
}
found my answer, can't use pdfbox to do it, although the alternative is just as simple. Use the desktop to print the file! example code as follows
public void printOrder(){
try {
File myFile = new File(finished);
//Desktop.getDesktop().open(myFile);
Desktop.getDesktop().print(myFile);
doc.close();
} catch (IOException ex) {
// no application registered for PDFs
}
}
I'm trying to update a Microsoft Word document using Apache POI. The msword document is a template that contains a number of placeholders in the form "${place.holder}" and all I need to do is to replace the holders with specific values. What I've got so far is
private void start() throws FileNotFoundException, IOException {
POIFSFileSystem fsfilesystem = null;
HWPFDocument hwpfdoc = null;
InputStream resourceAsStream = getClass().getResourceAsStream("/path/to/document/templates/RMA FORM.doc");
try {
fsfilesystem = new POIFSFileSystem(resourceAsStream );
hwpfdoc = new HWPFDocument(fsfilesystem);
Range range = hwpfdoc.getRange();
range.replaceText("${rma.number}","08739");
range.replaceText("${customer.name}", "Roger Swann");
FileOutputStream fos = new FileOutputStream(new File("C:\\temp\\updatedTemplate.doc"));
hwpfdoc.write(fos);
fos.flush();
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
The program runs without errors. If I look in the output file with a Hex editor I can see that the placeholders have been replaced by the program. However, when I try to open the document with MSWord, MSWord crashes.
Is there a step (series of steps) that I'm missing, or am I basically out of luck with this? Do I need to adjust any counters because the length of the replacement text is not the same as the length of the replaced text?
Regards
use new FileInputStream() instead of getClass().getResourceAsStream("/path/to/document/templates/RMA FORM.doc");