I'm using iText to dynamically generate PDF docs. Now I'm trying to dynamically create a barcode in this PDF. Adobe Live Cycle has a barcode function built-in. You can just drag the barcode text box on the page and it's created.
Problem:
I placed the barcode field in the PDF. Then pass a number to the barcode field from the JSP page. But only the number appears. The barcode lines never display
The number, 20099002, is visible on the PDF doc, but the barcode lines fail to appear. I tried several other barcode options in LiveCycle but the all give the same result.
OurJavaPage.java
public class ExampleForm extends BaseOutput {
private static final Log LOG = LogFactory.getLog(ExampleForm.class);
public OutputStream generate() throws IOException, DocumentException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PdfReader reader;
reader = new PdfReader(BASEDIR + "MailingExample.pdf");
PdfStamper stamper = new PdfStamper(reader, baos);
Participant participantHome = home.getParticipant();
Set<Location> homeLocs = participantHome.getLocations();
final AcroFields form = stamper.getAcroFields();
setFormField(form, "addrNumber[0]", addrMaster.getStreetNum());
setFormField(form, "dateMiddle[0]", formatDate("MM-dd-yyyy", new Date()));
// *********** Here's the problem *****************************
setFormField(form, "Code128ABarcode1[0]", "20099002");
// ************************************************************
debugAcrobatForm("ExampleForm", form);
stamper.setFormFlattening(true);
stamper.close();
return baos;
}
}
Operating System: Linux
Programming: Java, .jsp, iText
Software: Adobe Live Cycle Designer ES 8.1
Problem solved!!!
I contacted iText and they suggested that I change this line.
From:
stamper.setFormFlattening(true);
To:
stamper.setFormFlattening(false);
It worked.
Does your software embed the barcode as a graphic or as a font representation of characters?
If the latter, is it embedding the font into the PDF?
Did you ask on the very active IText mailing list?
If this was a dynamic XFA form created with LiveCycle, then using form flattening will cause you to lose your form fields. Static XFA forms should work though.
Reference: http://itext.ugent.be/library/question.php?id=30
XFA support in iText is improving but spotty at best.
u have to add barcode font in ur system (font library), then it will be visible in ur font drop-down. Use acro-field (text) and set that font in this acro-field. Ur problem will be solved.
also, use setformflattening=true as it will make pdf uneditable
it works just fine for me.. maybe its got to do with the way you make the template in livecycle designer (static or dynamic)...
see sample here
http://1t3xt.info/examples/browse/?page=example&id=433
Regards
Raghavendra Samant
Related
We have a program that modifies a pdf for mailing. We noticed an issue with docusign envelope fields and signatures. They do not stay on the pdf when we modify. I tried everything i can think of in pdfbox.
The only workaround i found is foxit flatten signature when printing and adobe save as pdf do create a flattened pdf that works. I cannot render the whole pdf to an image because i need the pdf text fields to be evaluated programatically.
Anyway to create the same flatten that foxit and adobe to with pdfbox. I am so stumped:(
Not sure if this helps but I am able to access the item in the document this way.
PDDocument doc = PDDocument.load( myFile );
PDPageTree allPages = doc.getDocumentCatalog().getPages();
PDPage page1 = allPages.get(1);
COSDictionary pageDict = page1.getCOSObject();
COSDictionary newPageDict = new COSDictionary(pageDict);
COSDictionary test = newPageDict.getCOSDictionary(COSName.RESOURCES);
test = test.getCOSDictionary(COSName.XOBJECT);
test = test.getCOSDictionary(COSName.F);
test = test.getCOSDictionary(COSName.RESOURCES);
test = test.getCOSDictionary(COSName.XOBJECT);
The item exists in a COSName{X0}, but it does not appear pdfbox can access this so I cannot flatten it. I'd like to itterate through entire document for any non identifiable COSNames and render it to an image because that does work then use that image? Anyway to do this?
What I am trying to achieve is to replace a text in pdf file. I have the following code:
PdfReader reader = new PdfReader("test.pdf");
PdfDictionary dict = reader.getPageN(1);
PdfObject object = dict.getDirectObject(PdfName.CONTENTS);
if (object instanceof PRStream)
{
PRStream stream = (PRStream) object;
byte[] data = PdfReader.getStreamBytes(stream);
System.out.println(new String(data));
stream.setData(new String(data).replace("application", "HELLO WORLD").getBytes());
}
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream("test-output.pdf"));
stamper.close();
reader.close();
When I trying to print out to see the data (System.out.println(new String(data))), "application" is showing as "ap)-4(plica)-3(tion", that's the reason why I failed to replace the text, any idea or other method that can achieve what I trying to achieve?
You will not be able to do this with iText.
Believe me, this is one of the most frustrating discoveries about PDFs: you can build them with iText, but you cannot go back later and replace text with something else, as you have in your example.
There really is not much you can do about it. Once text is there, you can't modify it.
All that notwithstanding, you can usually ADD new content (text, images, etc.) to an existing PDF. So... if you can alter the universe slightly and create a PDF with empty space in the correct size, you can go back later and use the PdfStamper class to "stamp" on another layer of graphical content.
More on this can be found in the iText documentation, and in this fine question:
How to add Content to a PDF using iText PdfStamper
I have these lines of codes that I have being trying to use to read pdf file with Apache pdfBox.
private void readPdf(){
try {
File PDF_Path = new File("/home/olyjosh/Downloads/my project.pdf");
PDDocument inputPDF = PDDocument.load(PDF_Path);
List<PDPage> allPages = inputPDF.getDocumentCatalog().getAllPages();
PDPage testPage = (PDPage) allPages.get(5);
System.out.println("Number of pages "+allPages.size());
PDFPagePanel pdfPanel = new PDFPagePanel();
jPanel1.add(pdfPanel);
pdfPanel.setPage(testPage);
// this.revalidate();
inputPDF.close();
} catch (IOException ex) {
Logger.getLogger(NewJFrame.class.getName()).log(Level.SEVERE, null, ex);
}
}
I want this pdf to be displayed on swing component like jPanel but this will only display the panel with the expected content of the pdf file. However, I was able to display the pdf as image using
convertToImage = testPage.convertToImage();
Please, how do I work around this or what am I doing wrong.
Apache PDF-Box has a mailing list where I was able to ask the same question and this was the response I got
This was removed in 2.0 because it made trouble. Obviously, it doesn't work for 1.8 either, at least for you, so why bother?
There are two ways to display, either get a BufferedImage (renderImage / renderImageWithDPI) and display that somehow (see in PDFDebugger how to do it), or renderPageToGraphics which renders to a graphics device object.
If you really want to get the source code of the deleted PDFReader application (which includes PDFPagePanel), use svn to get revision 1702125 or earlier, that should have it. But if it didn't work for you in 1.8, it won't work for you now.
The point is that swing display of PDF pages isn't part of the API, it's part of some tool (now: in PDFDebugger, previously: in PDFReader)
You need to have some understanding of awt / swing. If you don't, learn it, or hire somebody. (That's what we did, and the best is: google paid it, as part of the google summer of code)
Tilman
I am using pdfbox to fill up a form in my pdf file, application is able to show number of available fields on the form but it returns the following error
Messages:
Error: Don't know how to calculate the position for non-simple fonts
File: org/apache/pdfbox/pdmodel/interactive/form/PDAppearance.java
Line number: 616
Code
.....
while (fieldsIter.hasNext()) {
PDField field = (PDField) fieldsIter.next();
setField(pdf, field.getPartialName(), "My input");
//setField(pdf, field.getFullyQualifiedName(), "My input");
}
.....
public void setField(PDDocument pdfDocument, String name, String value) throws
IOException {
PDDocumentCatalog docCatalog = pdfDocument.getDocumentCatalog();
PDAcroForm acroForm = docCatalog.getAcroForm();
PDField field = acroForm.getField(name);
if (field != null) {
field.setValue(value);
} else {
System.err.println("No field found with name:" + name);
}
}
Please let me know if you need any other part of the code.
There seems to be a bug in pdfbox that occurs in various circumstances where it can't find the relevant font. The only workaround I've been able to find is just skipping the update appearance code that's run in PDTextbox.setValue. You can "force" the value to be updated by just doing:
COSString fieldValue = new COSString("Awesome field value");
textbox.getDictionary().setItem(COSName.V, fieldValue);
Presumably, in all but corner cases, the PDF viewer can handle rendering the font, and just setting the V item for the field should suffice. Subjectively the documents I've generated open fine in Acrobat and OS X preview.
Related issue:
https://issues.apache.org/jira/browse/PDFBOX-1550
Edit to add: by default acrobat seems to create fields with a visible text area size of 0. For documents with this problem, you can get around this by adding textbox.getDictionary().setItem(COSName.AP, null); and hoping that the reader can handle rendering the appearance correctly.
Use another PDF if that works means PDFBox is not compatible with the first pdf.
I had the same issue with a PDF and I ended up solving it by editing the PDF form field (with Abobe Acrobat Pro) and setting an specific font.
The problem was that the problematic field didn't specify any font at all.
Hope it helps!
I also had this issue, the problem was that the PDF did not embed the font used.
Moreover the Preflight tools from Acrobat pro seemed unable to fix the PDF. I ended up recreating the PDF and now it is working fine.
This happend to me by using Adobe Pro and merging to PDFs into one. After this the resulting PDF was not able to be used with PDFBox also the original PDFs worked. After a little research i found out, that the merge process destryos the font information. Just reset the fonts and it should work!
Best regards!
I am trying to generate a PDF document from a *.doc document.
Till now and thanks to stackoverflow I have success generating it but with some problems.
My sample code below generates the pdf without formatations and images, just the text.
The document includes blank spaces and images which are not included in the PDF.
Here is the code:
in = new FileInputStream(sourceFile.getAbsolutePath());
out = new FileOutputStream(outputFile);
WordExtractor wd = new WordExtractor(in);
String text = wd.getText();
Document pdf= new Document(PageSize.A4);
PdfWriter.getInstance(pdf, out);
pdf.open();
pdf.add(new Paragraph(text));
docx4j includes code for creating a PDF from a docx using iText. It can also use POI to convert a doc to a docx.
There was a time when we supported both methods equally (as well as PDF via XHTML), but we decided to focus on XSL-FO.
If its an option, you'd be much better off using docx4j to convert a docx to PDF via XSL-FO and FOP.
Use it like so:
wordMLPackage = WordprocessingMLPackage.load(new java.io.File(inputfilepath));
// Set up font mapper
Mapper fontMapper = new IdentityPlusMapper();
wordMLPackage.setFontMapper(fontMapper);
// Example of mapping missing font Algerian to installed font Comic Sans MS
PhysicalFont font
= PhysicalFonts.getPhysicalFonts().get("Comic Sans MS");
fontMapper.getFontMappings().put("Algerian", font);
org.docx4j.convert.out.pdf.PdfConversion c
= new org.docx4j.convert.out.pdf.viaXSLFO.Conversion(wordMLPackage);
// = new org.docx4j.convert.out.pdf.viaIText.Conversion(wordMLPackage);
OutputStream os = new java.io.FileOutputStream(inputfilepath + ".pdf");
c.output(os);
Update July 2016
As of docx4j 3.3.0, Plutext's commercial PDF renderer is docx4j's default option for docx to PDF conversion. You can try an online demo at converter-eval.plutext.com
If you want to use the existing docx to XSL-FO to PDF (or other target supported by Apache FOP) approach, then just add the docx4j-export-FO jar to your classpath.
Either way, to convert docx to PDF, you can use the Docx4J facade's toPDF method.
The old docx to PDF via iText code can be found at https://github.com/plutext/docx4j-export-FO/.../docx4j-extras/PdfViaIText/
WordExtractor just grabs the plain text, nothing else. That's why all you're seeing is the plain text.
What you'll need to do is get each paragraph individually, then grab each run, fetch the formatting, and generate the equivalent in PDF.
One option may be to find some code that turns XHTML into a PDF. Then, use Apache Tika to turn your word document into XHTML (it uses POI under the hood, and handles all the formatting stuff for you), and from the XHTML on to PDF.
Otherwise, if you're going to do it yourself, take a look at the code in Apache Tika for parsing word files. It's a really great example of how to get at the images, the formatting, the styles etc.
I have succesfully used Apache FOP to convert a 'WordML' document to PDF. WordML is the Office 2003 way of saving a Word document as xml. XSLT stylesheets can be found on the web to transform this xml to xml-fo which in turn can be rendered by FOP into PDF (among other outputs).
It's not so different from the solution plutext offered, except that it doesn't read a .doc document, whereas docx4j apparently does. If your requirements are flexible enough to have WordML style documents as input, this might be worth looking into.
Good luck with your project!
Wim
Use OpenOffice/LbreOffice and JODConnector
This also mostly works for .doc to .docx. Problems with graphics that I have not yet worked out though.
private static void transformDocXToPDFUsingJOD(File in, File out)
{
OfficeDocumentConverter converter = new OfficeDocumentConverter(officeManager);
DocumentFormat pdf = converter.getFormatRegistry().getFormatByExtension("pdf");
converter.convert(in, out, pdf);
}
private static OfficeManager officeManager;
#BeforeClass
public static void setupStatic() throws IOException {
/*officeManager = new DefaultOfficeManagerConfiguration()
.setOfficeHome("C:/Program Files/LibreOffice 3.6")
.buildOfficeManager();
*/
officeManager = new ExternalOfficeManagerConfiguration().setConnectOnStart(true).setPortNumber(8100).buildOfficeManager();
officeManager.start();
}
#AfterClass
public static void shutdownStatic() throws IOException {
officeManager.stop();
}
You need to be running LibreOffice as a serverto make this work.
From the command line you can do this using;
"C:\Program Files\LibreOffice 3.6\program\soffice.exe" -accept="socket,host=0.0.0.0,port=8100;urp;LibreOffice.ServiceManager" -headless -nodefault -nofirststartwizard -nolockcheck -nologo -norestore
Another option I came across recently is using the OpenOffice (or LibreOffice) API (see here). I have not been able to get into this but it should be able to open documents in various formats and output them in a pdf format. If you look into this, let me know how it worked!