How to insert the values in page pdf with itext pdf - java

I tried to insert values into the pdf like this :
String nomeArquivo ="tempRelatorioPDF.pdf";
File file = new File(nomeArquivo);
file.createNewFile();
PdfWriter.getInstance(doc, new FileOutputStream(file));
doc.open();
PdfWriter writer = PdfWriter.getInstance(doc, new `FileOutputStream(nomeArquivo));`
Document doc = new Document(PageSize.A4.rotate());
while(iteratorRow.hasNext()){
Object valorCelulaRow = iteratorRow.next();
Paragraph p3 = new Paragraph();
p3.add(colunas[i].getName());
p3.add("\n");
doc.add((com.itextpdf.text.Element)p3);
if(valorCelulaRow != null){
Paragraph p = new Paragraph(valorCelulaRow.toString());
doc.add(p);
}
doc.close();
Displays the error: PDF FILE IS CORRUPT actually gives error opening the file appears to be corrupt.
**
ADJUSTMENTS PRIOR TO GET TO THIS POINT
**
I use the following libraries for this:
import com.itextpdf.text.Chunk;
import com.itextpdf.text.ListItem;
*>>>>> import com.itextpdf.text.Paragraph;*
...
import com.itextpdf.text.DocumentException;
*>>>>> import com.lowagie.text.Document;*
import com.lowagie.text.Element;
import com.lowagie.text.Font;
...
There is a conlito when retreat commented library and additio the itext. the doc.Add in error.
import com.itextpdf.text.Document;
// import com.lowagie.text.Document;
ERROR After the change of import reference
Document doc = new Document(PageSize.A4.rotate());
//The constructor Document(Rectangle) is undefined
PdfWriter.getInstance(doc, new FileOutputStream(file));
PdfWriter writer = PdfWriter.getInstance(doc, new FileOutputStream(nomeArquivo));
//The method getInstance(Document, OutputStream) in the type PdfWriter is not applicable for the arguments (Document, FileOutputStream)
[partially solved]
Add the "(com.itextpdf.text.Element)"
change "Add" for "add";
The debug data is loaded into the variable 'p' and 'P3'. But the PDF document is generated with 0kb.

This should work, I'm not sure how it would not. I don't think you should be casting anything. Paragraph allows for direct construction using a String parameter. I take it you want the paragraph to have value of valueCellRow.toString() correct?
Document doc = new Document(PageSize.A4.rotate());
while(iteratorRow.hasNext()) {
Object valorCelulaRow = iteratorRow.next();
if(valorCelulaRow != null) {
Paragraph p = new Paragraph(valueCellRow.toString());
doc.Add (p);
}
}
doc.close();
If all else fails, it's your libraries (com.lowagie.text.Element vs com.itextpdf.text.Element) clashing. Try use:
doc.Add((com.itextpdf.text.Element) p);
Though you shouldn't need to.

Related

iTextpdf 5.5.8 With JavaEE method PdfCopy addDocument undefined

I am trying to create a pdf with pdfcopy, which is composed with 2 sides of a card.
I am running this with Jetty. but i keep getting this error :
[ERROR] The method addDocument(PdfReader) is undefined for the type PdfCopy
My code :
import com.itextpdf.text.pdf.PdfCopy;
public static File exportCards(Person p) throws IOException, DocumentException {
Document document = new Document();
File temp = File.createTempFile("temp_file_name_", ".tmp");
PdfCopy copy = new PdfSmartCopy(document, new FileOutputStream(temp));
document.open();
PdfReader reader;
PdfReader reader_2;
reader = new PdfReader("FrontStatic.pdf");
reader_2 = new PdfReader("BackStatic.pdf");
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(temp+"_f"));
PdfStamper stamper_2 = new PdfStamper(reader_2, new FileOutputStream(temp+"_r"));
AcroFields form = stamper.getAcroFields();
AcroFields form_2 = stamper_2.getAcroFields();
form.removeXfa();
//Recto
form.setField("form1[0].#subform[0].firstname[0]", p.getFirstName());
form.setField("form1[0].#subform[0].lastname[0]", p.getLastName());
//Verso
form_2.setField("form1[0].#subform[0].number[0]", String.valueOf(p.getIdentityID()));
copy.addDocument(reader);
copy.addDocument(reader_2);
stamper.close();
stamper_2.close();
reader.close();
reader_2.close();
//copy.close();
//document.close();
return temp;
i run the same code on a new program to test only this part, without anything else, and it's running, at least i get the 2 temp file "Stamp" with my data. I do not get the merged document.
Even if i still have a problem with my method to get the final document the error occures only with de Server Web program.
Does someone have an idea ?
Thank you for your time.

Merge documents to create TOC in iText (Java)

When creating documents with iText that need a table of contents, I have usually used a process where I create the main document in memory, create the TOC as a separate document in memory (using dummy links), merge them as a third document, and then use a PdfStamper to reconcile the links into the document and write it to a file.
This works with all versions of iText except the most recent (5.5.6). I will include a simple program that does this process (the real programs are much more complex). When running this with iText 5.5.5 or earlier, it creates the desired document (2 pages with the first page containing text that provides a link to open the second page). With 5.5.6 the call to makeRemoteNamedDestinationsLocal causes an exception com.itextpdf.text.pdf.PdfDictionary cannot be cast to com.itextpdf.text.pdf.PdfArray.
As this had always worked until the latest version, I have some suspicion that this may be a bug in the newest version. Is this a bug, or am I doing something wrong? How should I do this task if it is not a bug? Additionally, how are bug reports usually submitted for iText? From the website, it looks like they expect a question to be submitted here as a report.
import com.itextpdf.text.pdf.*;
import com.itextpdf.text.pdf.draw.*;
import java.io.*;
// WORKS CORRECTLY USING itext version 5.5.5
// FAILS WITH 5.5.6
// CAUSES AN EXCEPTION
// "com.itextpdf.text.pdf.PdfDictionary cannot be cast to com.itextpdf.text.pdf.PdfArray"
// with makeRemoteNamedDestinationsLocal()
public class testPdf {
public static void main (String[] args) throws Exception {
// Create simple document
ByteArrayOutputStream main = new ByteArrayOutputStream();
Document doc = new Document(new Rectangle(612f,792f),54f,54f,36f,36f);
PdfWriter pdfwrite = PdfWriter.getInstance(doc,main);
doc.open();
doc.add(new Paragraph("Testing Page"));
doc.close();
// Create TOC document
ByteArrayOutputStream two = new ByteArrayOutputStream();
Document doc2 = new Document(new Rectangle(612f,792f),54f,54f,36f,36f);
PdfWriter pdfwrite2 = PdfWriter.getInstance(doc2,two);
doc2.open();
Chunk chn = new Chunk("<<-- Link To Testing Page -->>");
chn.setRemoteGoto("DUMMY.PDF","page-num-1");
doc2.add(new Paragraph(chn));
doc2.close();
// Merge documents
ByteArrayOutputStream three = new ByteArrayOutputStream();
PdfReader reader1 = new PdfReader(main.toByteArray());
PdfReader reader2 = new PdfReader(two.toByteArray());
Document doc3 = new Document();
PdfCopy DocCopy = new PdfCopy(doc3,three);
doc3.open();
DocCopy.addPage(DocCopy.getImportedPage(reader2,1));
DocCopy.addPage(DocCopy.getImportedPage(reader1,1));
DocCopy.addNamedDestination("page-num-1",2,new PdfDestination(PdfDestination.FIT));
doc3.close();
// Fix references and write to file
PdfReader finalReader = new PdfReader(three.toByteArray());
// Fails on this line
finalReader.makeRemoteNamedDestinationsLocal();
PdfStamper stamper = new PdfStamper(finalReader,new FileOutputStream("Testing.pdf"));
stamper.close();
}
}
You have detected a bug that was introduced in iText 5.5.6. This has already been fixed in our repository:
Thank you for reporting this bug. You can find the fix on github: https://github.com/itext/itextpdf/commit/eac1a4318e6c31b054e0726ad44d0da5b8a720c2

How to read raw data, say only text, from a file(word document, excel) without format? [duplicate]

The strings I'm (programmatically) getting from MS Word files when using Apache POI are not the same text I can look at when I open the files with MS Word.
When using the following code:
File someFile = new File("some\\path\\MSWFile.doc");
InputStream inputStrm = new FileInputStream(someFile);
HWPFDocument wordDoc = new HWPFDocument(inputStrm);
System.out.println(wordDoc.getText());
the output is a single line with many 'invalid' characters (yes, the 'boxes'), and many unwanted strings, like "FORMTEXT", "HYPERLINK \l "_Toc##########"" ('#' being numeric digits), "PAGEREF _Toc########## \h 4", etc.
The following code "fixes" the single-line problem, but maintains all the invalid characters and unwanted text:
File someFile = new File("some\\path\\MSWFile.doc");
InputStream inputStrm = new FileInputStream(someFile);
WordExtractor wordExtractor = new WordExtractor(inputStrm);
for(String paragraph:wordExtractor.getParagraphText()){
System.out.println(paragraph);
}
I don't know if I'm using the wrong method for extracting the text, but that's what I've come up with when looking at POI's quick-guide. If I am, what is the correct approach?
If that output is correct, is there a standard way for getting rid of the unwanted text, or will I have to write a filter of my own?
This class can read both .doc and .docx files in Java. For this I'm using tika-app-1.2.jar:
/*
* This class is used to read .doc and .docx files
*
* #author Developer
*
*/
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.URL;
import org.apache.tika.detect.DefaultDetector;
import org.apache.tika.detect.Detector;
import org.apache.tika.io.TikaInputStream;
import org.apache.tika.metadata.Metadata;
import org.apache.tika.parser.AutoDetectParser;
import org.apache.tika.parser.ParseContext;
import org.apache.tika.parser.Parser;
import org.apache.tika.sax.BodyContentHandler;
import org.xml.sax.ContentHandler;
class TextExtractor {
private OutputStream outputstream;
private ParseContext context;
private Detector detector;
private Parser parser;
private Metadata metadata;
private String extractedText;
public TextExtractor() {
context = new ParseContext();
detector = new DefaultDetector();
parser = new AutoDetectParser(detector);
context.set(Parser.class, parser);
outputstream = new ByteArrayOutputStream();
metadata = new Metadata();
}
public void process(String filename) throws Exception {
URL url;
File file = new File(filename);
if (file.isFile()) {
url = file.toURI().toURL();
} else {
url = new URL(filename);
}
InputStream input = TikaInputStream.get(url, metadata);
ContentHandler handler = new BodyContentHandler(outputstream);
parser.parse(input, handler, metadata, context);
input.close();
}
public void getString() {
//Get the text into a String object
extractedText = outputstream.toString();
//Do whatever you want with this String object.
System.out.println(extractedText);
}
public static void main(String args[]) throws Exception {
if (args.length == 1) {
TextExtractor textExtractor = new TextExtractor();
textExtractor.process(args[0]);
textExtractor.getString();
} else {
throw new Exception();
}
}
}
To compile:
javac -cp ".:tika-app-1.2.jar" TextExtractor.java
To run:
java -cp ".:tika-app-1.2.jar" TextExtractor SomeWordDocument.doc
There are two options, one provided directly in Apache POI, the other via Apache Tika (which uses Apache POI internally).
The first option is to use WordExtractor, but wrap it in a call to stripFields(String) when calling it. That will remove the text based fields included in the text, things like HYPERLINK that you've seen. Your code would become:
NPOIFSFileSystem fs = new NPOIFSFileSytem(file);
WordExtractor extractor = new WordExtractor(fs.getRoot());
for(String rawText : extractor.getParagraphText()) {
String text = extractor.stripFields(rawText);
System.out.println(text);
}
The other option is to use Apache Tika. Tika provides text extraction, and metadata, for a wide variety of files, so the same code will work for .doc, .docx, .pdf and many others too. To get clean, plain text of your word document (you can also get XHTML if you'd rather), you'd do something like:
TikaConfig tika = TikaConfig.getDefaultConfig();
TikaInputStream stream = TikaInputStream.get(file);
ContentHandler handler = new BodyContentHandler();
Metadata metadata = new Metadata();
tika.getParser().parse(input, handler, metadata, new ParseContext());
String text = handler.toString();
Try this, works for me and is purely a POI solution. You will have to look for the HWPFDocument counterpart though. Make sure the document you are reading predates Word 97, else use XWPFDocument like I do.
InputStream inputstream = new FileInputStream(m_filepath);
//read the file
XWPFDocument adoc= new XWPFDocument(inputstream);
//and place it in a xwpf format
aString = new XWPFWordExtractor(adoc).getText();
//gets the full text
Now if you want certain parts you can use the getparagraphtext but dont use the text extractor, use it directly on the paragraph like this
for (XWPFParagraph p : adoc.getParagraphs())
{
System.out.println(p.getParagraphText());
}

error in converting word document to pdf using iText

The below is the code that i used to convert a word document to pdf. After compiling the code, the PDF file is generated. But the file contains some junk characters along with the word document content. Please help me to know what modification should i do to get rid of the junk characters.
The code i used is:
import com.lowagie.text.Document;
import com.lowagie.text.Paragraph;
import com.lowagie.text.pdf.PdfWriter;
import java.io.File;
import java.io.FileOutputStream;
public class PdfConverter
{
private void createPdf(String inputFile, String outputFile)//, boolean isPictureFile)
{
Document pdfDocument = new Document();
String pdfFilePath = outputFile;
try
{
FileOutputStream fileOutputStream = new FileOutputStream(pdfFilePath);
PdfWriter writer = null;
writer = PdfWriter.getInstance(pdfDocument, fileOutputStream);
writer.open();
pdfDocument.open();
/*if (isPictureFile)
{
pdfDocument.add(com.lowagie.text.Image.getInstance(inputFile));
}
else
{ */
File file = new File(inputFile);
pdfDocument.add(new Paragraph(org.apache.commons.io.FileUtils.readFileToString(file)));
//}
pdfDocument.close();
writer.close();
System.out.println("PDF has been generted");
}
catch (Exception exception)
{
System.out.println("Document Exception!" + exception);
}
}
public static void main(String args[])
{
PdfConverter pdfConversion = new PdfConverter();
pdfConversion.createPdf("C:/test.doc", "C:/test.pdf");//, true);
}
}
Thanks for you help.
Only because you name your class PdfConverter you don't have one. All you do is reading the binary content as a String and writing this as one paragraph (and that's what you see). This approach will definitively not be successful. See https://stackoverflow.com/questions/437394 for a similar question.
If you are interested just in the content of your word document, you might want to give Apache POI - the Java API for Microsoft Documents a try to read your the document not at binary level but on a hight abstraction level. If your Word document has a simple (and I mean a really simple) structure you might get reasonable results.
To do this, you will have to read the doc file correctly and then use the read data to create the PDF file.
What you are doing right now is that you are reading data from doc file, which is having garbage values since you are not using proper API to read the data, and then storing the obtained garbage data in the PDF file. Hence the issue.

How to generate a downloadable PDF with pdfbox (Corrupted PDF)?

How do I make a PDF file downloadable in a link?
I'm building a web application using JSF, when the user clicks in a "Save as PDF" link a PDF should be available to be downloaded.
So far I've a working code that generates the PDF file, but the file is saved on my desktop and what I want to do is that when the user clicks on the link the pdf file should be downloadable instead of being stored in the app.
UPDATE 3:
Thank you for your help guys, I modifed my code with your suggestions and it's working.
UPDATE 2:
I'm getting the following error: Adoble Reader could not open "yourfile.pdf" because is either not a supported file type or because the file has been damaged
UPDATE 1:
I'm adding my current code with the changes you have pointed me out, however I'm still struggling to make this work
This is my method that generated the PDF:
public ByteArrayOutputStream createPDF() throws IOException, COSVisitorException {
PDDocument document;
PDPage page;
PDFont font;
PDPageContentStream contentStream;
PDJpeg front;
PDJpeg back;
InputStream inputFront;
InputStream inputBack;
ByteArrayOutputStream output = new ByteArrayOutputStream();
// Creating Document
document = new PDDocument();
// Creating Pages
for(int i=0; i<2; i++) {
page = new PDPage();
// Adding page to document
document.addPage(page);
// Adding FONT to document
font = PDType1Font.HELVETICA;
// Retrieve Image to be added to the PDF
inputFront = new FileInputStream(new File("D:/Media/imageFront.jpg"));
inputBack = new FileInputStream(new File("D:/Media/imageBack.jpg"));
BufferedImage buffFront = ImageIO.read(inputFront);
BufferedImage resizedFront = Scalr.resize(buffFront, 460);
BufferedImage buffBack = ImageIO.read(inputBack);
BufferedImage resizedBack = Scalr.resize(buffBack, 460);
front = new PDJpeg(document, resizedFront);
back = new PDJpeg(document, resizedBack);
// Next we start a new content stream which will "hold" the to be created content.
contentStream = new PDPageContentStream(document, page);
// Let's define the content stream
contentStream.beginText();
contentStream.setFont(font, 8);
contentStream.moveTextPositionByAmount(10, 770);
contentStream.drawString("Amount: $1.00");
contentStream.endText();
contentStream.beginText();
contentStream.setFont(font, 8);
contentStream.moveTextPositionByAmount(200, 770);
contentStream.drawString("Sequence Number: 123456789");
contentStream.endText();
contentStream.beginText();
contentStream.setFont(font, 8);
contentStream.moveTextPositionByAmount(10, 760);
contentStream.drawString("Account: 123456789");
contentStream.endText();
contentStream.beginText();
contentStream.setFont(font, 8);
contentStream.moveTextPositionByAmount(200, 760);
contentStream.drawString("Captura Date: 04/25/2011");
contentStream.endText();
contentStream.beginText();
contentStream.setFont(font, 8);
contentStream.moveTextPositionByAmount(10, 750);
contentStream.drawString("Bank Number: 123456789");
contentStream.endText();
contentStream.beginText();
contentStream.setFont(font, 8);
contentStream.moveTextPositionByAmount(200, 750);
contentStream.drawString("Check Number: 123456789");
contentStream.endText();
// Let's close the content stream
contentStream.close();
}
// Finally Let's save the PDF
document.save(output);
document.close();
return output;
}
This is my servlet that call the previous code and generates the output and set the header:
try {
ByteArrayOutputStream output = new ByteArrayOutputStream();
output = createPDF();
response.addHeader("Content-Type", "application/force-download");
response.addHeader("Content-Disposition", "attachment; filename=\"yourFile.pdf\"");
response.getOutputStream().write(output.toByteArray());
} catch (Exception ex) {
ex.printStackTrace();
}
I'm not sure what I'm missing since when I try to open the PDF I got the error: Adoble Reader could not open "yourfile.pdf" because is either not a supported file type or because the file has been damaged
You need to set the proper http headers in order to tell the browser to download the file.
response.addHeader("Content-Type", "application/force-download")
response.addHeader("Content-Disposition", "attachment; filename=\"yourFile.pdf\"")
I have not done this in awhile, so bear with me, but what you do is instead of saving the pdf to a file via a stream, you save the stream in memory as a byte array and then when the user clicks on the link, you set the MIME type to PDF and then open up the byte array as a stream which you return as the response. I apologize for being a bit hazy on details. I think I also used jpedal and iText to get it done.
I can't show you all of the code, but here is some:
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.pdf.draw.DottedLineSeparator;
... // class, etc.
public ByteArrayOutputStream createOrderFormPdf(OrderFormDTO dto)
throws DocumentException {
Document document = new Document();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PdfWriter.getInstance(document, baos);
document.open();
Paragraph header = new Paragraph();
header.add(new Phrase(...));
OrderFormDtoPdfAdapter pdfAdapter = new OrderFormDtoPdfAdapter(dto);
header.add(pdfAdapter.getPdfHeaderTable());
document.add(header);
... // other code
Paragraph footer = new Paragraph();
footer.add(pdfAdapter.getPDFFooterTable());
document.add(footer);
Paragraph paragraph = new Paragraph();
PdfTableUtils.addEmptyLine(paragraph, 2);
document.add(paragraph);
document.add(new DottedLineSeparator());
document.close();
return baos;
}
You can then write out the baos on your response as a pdf using the correct MIME type.

Categories

Resources