I have a XFA based pdf form that we need to be populate using java.
Can you suggest the best approach.
I was able to generate the xfa xml for the pdf using iText.
public void readXfa(String srcPdfFilename, String destXMLFilename) throws IOException, ParserConfigurationException, SAXException, TransformerFactoryConfigurationError, TransformerException {
PdfReader reader = new PdfReader(srcPdfFilename);
XfaForm xfa = new XfaForm(reader);
Document doc = xfa.getDomDocument();
Transformer tf = TransformerFactory.newInstance().newTransformer();
tf.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
tf.setOutputProperty(OutputKeys.INDENT, "yes");
FileOutputStream os = new FileOutputStream(destXMLFilename);
tf.transform(new DOMSource(doc), new StreamResult(os));
reader.close();
}
I have the Pdf and Xfa XML generated from code above.
Can you please suggest me how to proceed further as I seem to be out of ideas. I tried to check the XFA documentation but does not seem right.
I do not have an xml and the pdf is very complex as it has many fields and is a dynamic XFA pdf form.
Your help and suggestions will be sincerely appreciated.
Please take a look at the FillXFA example. This example has a form (purchase_order.pdf) that contains a dynamic table:
Now we add data.xml, which is a set of data in the form of an XML file, we get this result: purchase_order_filled.pdf
As you can see, the data present in the XML file was added, as well as a number of empty rows (which correspond with empty data rows in the XML). As we added many rows, we even triggered a new page to be added to the PDF.
This is how it's done:
public void manipulatePdf(String src, String dest)
throws IOException, DocumentException {
PdfReader reader = new PdfReader(src);
PdfStamper stamper = new PdfStamper(reader,
new FileOutputStream(dest));
AcroFields form = stamper.getAcroFields();
XfaForm xfa = form.getXfa();
xfa.fillXfaForm(new FileInputStream(XML));
stamper.close();
reader.close();
}
There's another example here: XfaMovies. The xfa_movies.pdf document is a single page PDF without any buttons. We inject the data of 120 movies: movies.xml. The result is the 23-page PDF, xfa_filled_in.pdf.
NOTE: reading your code, you get an XML that contains the complete XFA stream. You don't need that, you only need the data. That's why I added the links to the XML files: they don't contain any XFA specific tags.
Related
I have created an accessible pdf through iText. However now i trying to take input from userlike Name, Address etc in JSP and place the input somewhere in the pdf.
User gives the input in the text area (like on SO) with the ability to mark the text as Bold or Italics or create lists (I am using widgEditor for this)
I am using PdfHtml to parse the input to the pdf. As far as i know there are 2 mehtods to make this work - convertToDocument() method and convertToElements() method.
I am using conconvertToElements() methods since convertToDocument() does not give us the ablity to place parsed input to a specific position in the pdf it simply puts the input at the top of Pdf.
I have refereed to C01E08_HelloWorld example
But while adding pdfptable to the document i am getting the following error.
Error - "The method add(AreaBreak) in the type Document is not applicable for the arguments (PdfTable)"
public void createPdf(String baseUri, String src, String dest) throws IOException {
ConverterProperties properties = new ConverterProperties();
properties.setBaseUri(baseUri);
List<IElement> elements = HtmlConverter.convertToElements(HTML+HTML2, properties);
PdfDocument pdf = new PdfDocument(new PdfWriter(dest));
Document document = new Document(pdf);
for (IElement element : elements) {
document.add(new Paragraph(element.getClass().getName()));
document.add((IBlockElement)element);
}
PdfPTable t = new PdfPTable(new float[] {1,1});
document.add(t);
document.close();
}
You are mixing iText 7 with iText 5 elements. PdfPTable is an iText 5 element and can't be used with the Document class of iText 7. Please use the com.itextpdf.layout.element.Table class.
Also, check your dependencies to remove the iText 5 dependency to avoid further confusion.
I am using itext to fill a template pdf, but I want to add tag to the template pdf and to the elements that I am trying to fill into it.
The first step that I made is trying to insert tag for the element that I am trying to insert into, here my code:
PdfReader reader = new PdfReader("myTemplatepath");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PdfStamper stamper = new PdfStamper(reader, baos);
PdfWriter writer = stamper.getWriter();
writer.setTagged(); //Make document tagged
But when I am using writer.setTagged() I have the following error:
java.lang.IllegalArgumentException: Tagging must be set before opening
the document
I saw, in this Topic that the problem is that PdfStamper doesn't support tagging,and the best solution is to create a new PDF and tagged it so my question is :
Since the topic is from 2007, there is any new implementation about this?
If not, what is the best way to doing so? The template that I have is not so simple and It has editable elements ( that i fill automaticatily).
I want to create non-printable pdf with using jasper, however users can display pdf but they can't print pdf. I don't want any pdf password restriction. I've researched jasper documentation but i couldn't found anything about it.
Is there anyway to solve my issue? I've already thank to you for your helps.
You can use iText's PdfStamper to post-process your PDF :
byte[] pdfContent = /* your PDF content here */;
ByteArrayOutputStream stampedPdfContent = new ByteArrayOutputStream();
PdfReader reader = new PdfReader(pdfContent);
PdfStamper stamper = new PdfStamper(reader, stampedPdfContent);
stamper.setEncryption(null, null, ~(PdfWriter.ALLOW_PRINTING), PdfWriter.STANDARD_ENCRYPTION_128);
stamper.close();
pdfContent = stampedPdfContent.toByteArray(); // your PDF is now non printable
I want to add a word in a sentence of a PDF content.
For example:
This is a sample content.
I want to insert a word in that content like this output.
This is a nice sample content.
This is a sample code for itextPdf that I found in the internet. Assumed that the content already exists and we want to modify it by adding a text in a sentence.
try {
//Create PdfReader instance.
PdfReader pdfReader =
new PdfReader(SRC);
//Create PdfStamper instance.
PdfStamper pdfStamper = new PdfStamper(pdfReader,
new FileOutputStream(DEST));
//Create BaseFont instance.
BaseFont baseFont = BaseFont.createFont(
BaseFont.TIMES_ROMAN,
BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
//Get the number of pages in pdf.
int pages = pdfReader.getNumberOfPages();
System.out.println(pdfStamper.getOverContent(1));
//Iterate the pdf through pages.
for(int i=1; i<=pages; i++) {
//Contain the pdf data.
PdfContentByte pageContentByte =
pdfStamper.getOverContent(i);
pageContentByte.setFlatness(89);
pageContentByte.beginText();
//Set text font and size.
pageContentByte.setFontAndSize(baseFont, 14);
pageContentByte.setTextMatrix(50, 720);
//Write text
pageContentByte.setWordSpacing(12);
pageContentByte.showText("hello world");
pageContentByte.endText();
}
//Close the pdfStamper.
pdfStamper.close();
System.out.println("PDF modified successfully.");
} catch (Exception e) {
e.printStackTrace();
}
I tried itextPdf and PdfBox but neither of them would work.
I can get the objects in the pdf document using PDFStreamParser of pdfbox.
PDFOperator{Td}, COSArray{[COSString{Name }, COSFloat{163.994}, COSString{____________________________________________________}, COSFloat{-8.03223}, COSString{________________________________________________________}]}, PDFOperator{TJ}, COSInt{19}, PDFOperator{TL}, PDFOperator{T*}, COSArray{[COSString{T}, COSInt{36}, COSString{itle}, COSFloat{0.997925}, COSString{ }, COSFloat{-94.9982}, COSString{_____________________________________________________________________________________________________________}]}, PDFOperator{TJ}, PDFOperator{T*}, COSArray{[
How can I implement a code that inserts a text?
Not.
Pdf is not a wysiwyg format. Internally, it's more like a file containing code. It has instructions for moving around a cursor, and drawing text and graphics at the tip of the cursor.
Then there's the fact that most instructions get packaged into "objects". All objects get placed in a dictionary that uses byte-offsets to reference them.
So inserting anything in a pdf-document will cause problems on 2 levels.
You would mess up the byte-offset of everything in the document
You would need to unscramble all the existing rendering operations to make sense of the document (to derive structure like lines of text, paragraph, etc) so that you can properly re-flow the content after you've inserted something.
Hence my short answer. You can't. And that immediately explains why none of the pdf toolkits you've tried can do it. It's simply an insanely hard task.
I have a PDF and FDF file and want to merge them into a single PDF. The .pdf has no fields, these are all included in the .fdf file, the contents of the fields also.
I have several solutions found, but these only works when the fields are stored in the pdf.
I would like to use iText with Java.
Does anyone have some demo code how I can solve my problem? Thank you!
Here's some code which only works when the fields are already present in the PDF
PdfReader pdfreader = new PdfReader(pdfInPath);
PdfStamper stamp = new PdfStamper(pdfreader, new FileOutputStream(pdfOutPath));
FdfReader fdfreader = new FdfReader(fdfInPath);
AcroFields form = stamp.getAcroFields();
form.setFields(fdfreader);
stamp.close();