how to pass a file path to PdfReader of iText - java

im using iText to get content of a pdf like this :
try {
String parsedText="";
File file = new File(getApplicationContext().getFilesDir(), "test.pdf");
PdfReader reader = new PdfReader(String.valueOf(file));
int n = reader.getNumberOfPages();
for (int i = 0; i <n ; i++) {
parsedText = parsedText+ PdfTextExtractor.getTextFromPage(reader, i+1).trim()+"\n"; //Extracting the content from the different pages
}
reader.close();
} catch (Exception e) {
Log.d("heh", String.valueOf(e));
}
but it returns the error:
/data/user/0/com.clementine.story_project/files/test.pdf not found as file or resource.
what am i doing wrong?

PdfReader doesn't accept file object, but it accept InputStream. So you can use the below code
Path path = file.toPath();
if(Files.exists(path)) {
PdfReader reader = new PdfReader(Files.newInputStream(path));
//other operations
}
Also, added a file exists condition before calling the stream.

Related

Merging of different file format into single pdf using itext is giving corrupt pdf

I have a multipart form in which different type of files will be uploaded in single request like pdf,png,jpg etc. I need to read these files and create final merged single pdf file. Does iText will support this kind of merger of different file types.
I can able to merge all image type but when i try to merge pdf with imgae getting some issues.Any sample example on this.Below code creating final pdf without images.
public void generateMergedPDF(Map<String, String> dataMap, MultipartFile[] files) throws Exception {
ClassPathResource resource = new ClassPathResource("templatepdfForm.pdf");
FileOutputStream userInfo = new FileOutputStream(new File("C:\\pdf\\megepath\\updateddocument.pdf"));
//Update filed values to template Starts
PdfReader reader = new PdfReader(resource.getInputStream());
PdfStamper stamper = new PdfStamper(reader, userInfo);
stamper.setFormFlattening(true);
AcroFields form = stamper.getAcroFields();
Map<String, Item> fieldMap = form.getFields();
for (String key : fieldMap.keySet()) {
String fieldValue = dataMap.get(key);
if (fieldValue != null) {
form.setField(key, fieldValue);
}
}
stamper.close();
//Update filed values to template Ends
Document mergePdfDoc = new Document();
PdfCopy pdfCopy;
boolean smartCopy = false;
FileOutputStream finalFile = new FileOutputStream("C:\\pdf\\finalmergedfile.pdf");
//Merge updated pdf with multipart content
if(smartCopy)
pdfCopy = new PdfSmartCopy(mergePdfDoc, finalFile);
else
pdfCopy = new PdfCopy(mergePdfDoc, finalFile);
PdfWriter writer = PdfWriter.getInstance(mergePdfDoc, finalFile);
mergePdfDoc.open();
PdfReader mergeReader = new PdfReader(new FileInputStream(new File("C:\\pdf\\megepath\\updateddocument.pdf")));
pdfCopy.addDocument(mergeReader);
pdfCopy.freeReader(mergeReader);
mergeReader.close();
PdfReader[] pdfReader = new PdfReader[files.length];
for(int i=0; i<=files.length-1;i++) {
if(FileContentType.APPLICATION_TYPE.getContentTypes().contains(files[i].getContentType())) {
//To add multipart pdf content
pdfReader[i] = new PdfReader(files[i].getInputStream());
pdfCopy.addDocument(pdfReader[i]);
pdfCopy.freeReader(pdfReader[i]);
pdfReader[i].close();
}else if(FileContentType.IMAGE_TYPE.getContentTypes().contains(files[i].getContentType())) {
//To add multipart image content
System.out.println("Image Type Loop");
Image fileImage = Image.getInstance(files[i].getBytes());
mergePdfDoc.setPageSize(fileImage);
mergePdfDoc.newPage();
claimImage.setAbsolutePosition(0, 0);
mergePdfDoc.add(fileImage);
}
}
pdfCopy.setMergeFields();
//mergePdfDoc.close(); //If i enable this close stream closed error
//writer.close(); //If i enable this close stream closed error
memInfo.close();
finalFile.close();
}

merge multiple pdfs in order

hey guys sorry for long post and bad language and if there is unnecessary details
i created multiple 1page pdfs from one pdf template using excel document
i have now
something like this
tempfile0.pdf
tempfile1.pdf
tempfile2.pdf
...
im trying to merge all files in one single pdf using itext5
but it semmes that the pages in the resulted pdf are not in the order i wanted
per exemple
tempfile0.pdf in the first page
tempfile1. int the 2000 page
here is the code im using.
the procedure im using is:
1 filling a from from a hashmap
2 saving the filled form as one pdf
3 merging all the files in one single pdf
public void fillPdfitext(int debut,int fin) throws IOException, DocumentException {
for (int i =debut; i < fin; i++) {
HashMap<String, String> currentData = dataextracted[i];
// textArea.appendText("\n"+pdfoutputname +" en cours de preparation\n ");
PdfReader reader = new PdfReader(this.sourcePdfTemplateFile.toURI().getPath());
String outputfolder = this.destinationOutputFolder.toURI().getPath();
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(outputfolder+"\\"+"tempcontrat"+debut+"-" +i+ "_.pdf"));
// get the document catalog
AcroFields acroForm = stamper.getAcroFields();
// as there might not be an AcroForm entry a null check is necessary
if (acroForm != null) {
for (String key : currentData.keySet()) {
try {
String fieldvalue=currentData.get(key);
if (key=="ADRESSE1"){
fieldvalue = currentData.get("ADRESSE1")+" "+currentData.get("ADRESSE2") ;
acroForm.setField("ADRESSE", fieldvalue);
}
if (key == "IMEI"){
acroForm.setField("NUM_SERIE_PACK", fieldvalue);
}
acroForm.setField(key, fieldvalue);
// textArea.appendText(key + ": "+fieldvalue+"\t\t");
} catch (Exception e) {
// e.printStackTrace();
}
}
stamper.setFormFlattening(true);
}
stamper.close();
}
}
this is the code for merging
public void Merge() throws IOException, DocumentException
{
File[] documentPaths = Main.objetapp.destinationOutputFolder.listFiles((dir, name) -> name.matches( "tempcontrat.*\\.pdf" ));
Arrays.sort(documentPaths, NameFileComparator.NAME_INSENSITIVE_COMPARATOR);
byte[] mergedDocument;
try (ByteArrayOutputStream memoryStream = new ByteArrayOutputStream())
{
Document document = new Document();
PdfSmartCopy pdfSmartCopy = new PdfSmartCopy(document, memoryStream);
document.open();
for (File docPath : documentPaths)
{
PdfReader reader = new PdfReader(docPath.toURI().getPath());
try
{
reader.consolidateNamedDestinations();
PdfImportedPage pdfImportedPage = pdfSmartCopy.getImportedPage(reader, 1);
pdfSmartCopy.addPage(pdfImportedPage);
}
finally
{
pdfSmartCopy.freeReader(reader);
reader.close();
}
}
document.close();
mergedDocument = memoryStream.toByteArray();
}
FileOutputStream stream = new FileOutputStream(this.destinationOutputFolder.toURI().getPath()+"\\"+
this.sourceDataFile.getName().replaceFirst("[.][^.]+$", "")+".pdf");
try {
stream.write(mergedDocument);
} finally {
stream.close();
}
documentPaths=null;
Runtime r = Runtime.getRuntime();
r.gc();
}
my question is how to keep the order of the files the same in the resulting pdf
It is because of naming of files. Your code
new FileOutputStream(outputfolder + "\\" + "tempcontrat" + debut + "-" + i + "_.pdf")
will produce:
tempcontrat0-0_.pdf
tempcontrat0-1_.pdf
...
tempcontrat0-10_.pdf
tempcontrat0-11_.pdf
...
tempcontrat0-1000_.pdf
Where tempcontrat0-1000_.pdf will be placed before tempcontrat0-11_.pdf, because you are sorting it alphabetically before merge.
It will be better to left pad file number with 0 character using leftPad() method of org.apache.commons.lang.StringUtils or java.text.DecimalFormat and have it like this tempcontrat0-000000.pdf, tempcontrat0-000001.pdf, ... tempcontrat0-9999999.pdf.
And you can also do it much simpler and skip writing into file and then reading from file steps and merge documents right after the form fill and it will be faster. But it depends how many and how big documents you are merging and how much memory do you have.
So you can save the filled document into ByteArrayOutputStream and after stamper.close() create new PdfReader for bytes from that stream and call pdfSmartCopy.getImportedPage() for that reader. In short cut it can look like:
// initialize
PdfSmartCopy pdfSmartCopy = new PdfSmartCopy(document, memoryStream);
for (int i = debut; i < fin; i++) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
// fill in the form here
stamper.close();
PdfReader reader = new PdfReader(out.toByteArray());
reader.consolidateNamedDestinations();
PdfImportedPage pdfImportedPage = pdfSmartCopy.getImportedPage(reader, 1);
pdfSmartCopy.addPage(pdfImportedPage);
// other actions ...
}

How can close PDF file if it is open?

I can create a PDF file with iText library in Java. This works, but now I have this problem, I execute the method, then I have a PDF file, its name is file.pdf and it is ok. Now I re-call the function to create the PDF file, its name is file.pdf but now, if the file is just open, I have an error.
FileNotFoundException:Impossible to access at file
And is ok this, so I want that if the file is open, from code, close the file then recreate the file and open it.
This is my code to create a PDF file:
public static void printFile(String nomeFolder, String nomeFile,List<Articoli> listaArticoli, boolean aprire)throws DocumentException{
String folderName = DateUtil.getDataGiornaliera();
nomeFolder = (new StringBuilder()).append(nomeFolder).append(nomeFile+"_"+folderName).append(".pdf").toString();
File f = new File(nomeFolder);
try {
OutputStream os = new FileOutputStream(f);
Document doc = new Document(PageSize.A4.rotate(), -65F, -65F, 85F, 40F);
PdfWriter docWriter = PdfWriter.getInstance(doc, os);
EndPageFoglioFatturaFatt hp2 = new EndPageFoglioFatturaFatt(nomeFolder, "Img/ineco1.jpg",folderName);
docWriter.setPageEvent(hp2);
FooterDocumenti hp = new FooterDocumenti(nomeFolder, "Img/ineco1.jpg",folderName);
docWriter.setPageEvent(hp);
doc.open();
float[] colonne = {0.7f,1.5f,4.5f,0.5f,0.5f,1.5f,1.5f,1.5f};
PdfPTable table = new PdfPTable(colonne);
table.setHeaderRows(1);
String[] intestazioni = {"C.ART","C.BARRE", "NOME ARTICOLO","IVA(%)", "Q.TA",
"PR.VENDITA", "ULT.PR.VENDITA", "ULT.DATA ACQUISTO"};
PdfPCell cell = new PdfPCell();
for(int i = 0; i< intestazioni.length; i++){
cell = new PdfPCell(new Paragraph(intestazioni[i], FontFactory.getFont("Century Gothic", 8F)));
cell.setGrayFill(0.9F);
cell.setUseAscender(true);
cell.setHorizontalAlignment(1);
cell.setVerticalAlignment(5);
cell.setBorderWidth(0.5F);
cell.setFixedHeight(15F);
table.addCell(cell);
}
//Vector v = db.eseguiQueryTuttiArticoli("SELECT ARTICOLIDETT.CodArticolo,NomeArticolo,Iva, Quantita,PrezzoAttuale, PrezzoRivenditore, PrezzoIngrosso, Soglia FROM Articolidett,Articoliquantita WHERE ARTICOLIDETT.CODARTICOLO = ARTICOLIQUANTITA.CODARTICOLO ORDER BY NOMEARTICOLO");
for (Articoli articoli : listaArticoli) {
cell = new PdfPCell(new Paragraph(articoli.getCodArticoloString(), FontFactory.getFont("Century Gothic", 10F)));
cell.setVerticalAlignment(5);
cell.setHorizontalAlignment(0);
cell.setColspan(0);
cell.setBorderWidth(0.5F);
table.addCell(cell);
....
....
CODE TO BUILD A FILE
.....
.....
}
doc.add(table);
doc.close();
os.close();
} catch (FileNotFoundException e) {
log.logStackTrace(e);
VisualMessageStampe.getErroreFileAperto();
}
catch(IOException exp)
{
log.logStackTrace(exp);
}
catch(DocumentException exp2)
{
log.logStackTrace(exp2);
}
if(aprire)
{
if(Desktop.isDesktopSupported())
{
try
{
Desktop.getDesktop().open(f.getCanonicalFile());
}
catch(IOException ex)
{
log.logStackTrace(ex);
}
} else
{
VisualMessageStampe.getErroreAcrobatInesistente();
}
}
}
How can I fixed my problem?
You cannot open an OutputStream into a file opened in external application (Adobe Reader or stuff). Some things you could do instead:
Create new filename for each iteration (creating tempfiles is cheap)
Check if file exists before you go and overwrite. If exists create a suffix (_1, _2, ...) and check that does not exist.
Alert user once you see that message to "please close PDF file before creating new"
Something like this might help:
protected File getFile(String nomeFile, String nomeFolder) {
String folderName = DateUtil.getDataGiornaliera();
nomeFolder = (new StringBuilder()).append(nomeFolder).append(nomeFile+"_"+folderName).append(".pdf").toString();
File f = new File(nomeFolder);
int suffix = 1;
while(f.exists()) {
nomeFolder = (new StringBuilder()).append(nomeFolder).append(nomeFile+"_"+folderName+"_"+(suffix++)).append(".pdf").toString();
f = new File(nomeFolder);
}
return f;
}

iText PdfAConformanceException: PDF array is out of bounds

i'm using iText 5.5.5 with Java5.
I'm trying to merge some PDF/A. when I got a "PdfAConformanceException: PDF array is out of bounds".
Trying to find error I find the "bad PDF" that cause the error and when I try to copy just it exception throw again. This error don't appear always, it appear just when this PDF/A is in the "job chain"; I tried with some other files and it's all fine. I cant share with you source PDF 'couse it's restricted.
That's my piece of code:
_log.info("Start Document Merge");
// Output pdf
ByteArrayOutputStream bos = new ByteArrayOutputStream();
com.itextpdf.text.Document document = new com.itextpdf.text.Document();
PdfCopy copy = new PdfACopy(document, bos, PdfAConformanceLevel.PDF_A_1B);
PageStamp stamp = null;
PdfReader reader = null;
PdfContentByte content = null;
int outPdfPageCount = 0;
BaseFont baseFont = BaseFont.createFont("Arial", BaseFont.WINANSI, BaseFont.EMBEDDED);
copyOutputIntents(reader, copy);
// Loop over the pages in that document
try {
int numberOfPages = reader.getNumberOfPages();
for (int i = 1; i <= numberOfPages; i++) {
PdfImportedPage pagecontent = copy.getImportedPage(reader, i);
_log.debug("Handling page numbering [" + i + "]");
stamp = copy.createPageStamp(pagecontent);
content = stamp.getUnderContent();
content.beginText();
content.setFontAndSize(baseFont, Configuration.NumPagSize);
content.showTextAligned(PdfContentByte.ALIGN_CENTER, String.format("%s %s ", Configuration.NumPagPrefix, i), Configuration.NumPagX, Configuration.NumPagY, 0);
content.endText();
stamp.alterContents();
copy.addPage(pagecontent);
outPdfPageCount++;
if (outPdfPageCount > Configuration.MaxPages) {
_log.error("Pdf Page Count > MaxPages");
throw new PackageException(Constants.ERROR_104_TEXT, Constants.ERROR_104);
}
}
copy.freeReader(reader);
reader.close();
copy.createXmpMetadata();
document.close();
} catch (Exception e) {
_log.error("Error during mergin Document, skip");
_log.debug(MiscUtil.stackToString(e));
}
return bos.toByteArray();
That's the full stacktrace:
com.itextpdf.text.pdf.PdfAConformanceException: PDF array is out of bounds.
at com.itextpdf.text.pdf.internal.PdfA1Checker.checkPdfObject(PdfA1Checker.java:269)
at com.itextpdf.text.pdf.internal.PdfAChecker.checkPdfAConformance(PdfAChecker.java:208)
at com.itextpdf.text.pdf.internal.PdfAConformanceImp.checkPdfIsoConformance(PdfAConformanceImp.java:71)
at com.itextpdf.text.pdf.PdfWriter.checkPdfIsoConformance(PdfWriter.java:3480)
at com.itextpdf.text.pdf.PdfWriter.checkPdfIsoConformance(PdfWriter.java:3476)
at com.itextpdf.text.pdf.PdfArray.toPdf(PdfArray.java:165)
at com.itextpdf.text.pdf.PdfDictionary.toPdf(PdfDictionary.java:149)
at com.itextpdf.text.pdf.PdfArray.toPdf(PdfArray.java:175)
at com.itextpdf.text.pdf.PdfDictionary.toPdf(PdfDictionary.java:149)
at com.itextpdf.text.pdf.PdfIndirectObject.writeTo(PdfIndirectObject.java:158)
at com.itextpdf.text.pdf.PdfWriter$PdfBody.write(PdfWriter.java:420)
at com.itextpdf.text.pdf.PdfWriter$PdfBody.add(PdfWriter.java:398)
at com.itextpdf.text.pdf.PdfWriter$PdfBody.add(PdfWriter.java:373)
at com.itextpdf.text.pdf.PdfWriter$PdfBody.add(PdfWriter.java:369)
at com.itextpdf.text.pdf.PdfWriter.addToBody(PdfWriter.java:843)
at com.itextpdf.text.pdf.PdfCopy.addToBody(PdfCopy.java:839)
at com.itextpdf.text.pdf.PdfCopy.addToBody(PdfCopy.java:821)
at com.itextpdf.text.pdf.PdfCopy.copyIndirect(PdfCopy.java:426)
at com.itextpdf.text.pdf.PdfCopy.copyIndirect(PdfCopy.java:446)
at com.itextpdf.text.pdf.PdfCopy.copyObject(PdfCopy.java:577)
at com.itextpdf.text.pdf.PdfCopy.copyDictionary(PdfCopy.java:503)
at com.itextpdf.text.pdf.PdfCopy.copyObject(PdfCopy.java:573)
at com.itextpdf.text.pdf.PdfCopy.copyDictionary(PdfCopy.java:503)
at com.itextpdf.text.pdf.PdfCopy.copyObject(PdfCopy.java:573)
at com.itextpdf.text.pdf.PdfCopy.copyDictionary(PdfCopy.java:493)
at com.itextpdf.text.pdf.PdfCopy.copyDictionary(PdfCopy.java:519)
at com.itextpdf.text.pdf.PdfCopy.addPage(PdfCopy.java:663)
at com.itextpdf.text.pdf.PdfACopy.addPage(PdfACopy.java:115)
at it.m2sc.engageone.documentpackage.generator.PackageGenerator.mergePDF(PackageGenerator.java:256)
In that specific case, the problem depends by a specific Font ( Gulim ) that is too big to be embedded in PDF/A-1 file. When that font was removed, everything war run fine.

Displaying contents of doc file in jTextPane

i m trying to display contents of a doc file into jTextPane. But it is displaying only the last line of document while on console it is displaying whole document.
I m using Apache POI library.
File file = null;
WordExtractor extractor = null ;
try {
file = new File("C:\\Users\\Siddique Ansari\\Documents\\CV Parser\\Siddique_Resume.doc");
FileInputStream fis=new FileInputStream(file.getAbsolutePath());
HWPFDocument document=new HWPFDocument(fis);
extractor = new WordExtractor(document);
String [] fileData = extractor.getParagraphText();
for(int i=0;i<fileData.length;i++){
System.out.println(fileData[i]);
jTextPane1.setText(fileData[i]);
}
}
catch(Exception exep){}
jTextPane1.setText(fileData[i]); will override the current value each time.
Instead, append to the underlying document:
Document doc = jTextPane1.getDocument();
// ... in your loop:
doc.insertString(doc.getLength(), fileData[i], null);
Instead of:
for(int i=0;i<fileData.length;i++){
System.out.println(fileData[i]);
jTextPane1.setText(fileData[i]);
}
try
StringBuilder content = new StringBuilder();
for(int i=0; i < fileData.length; i++){
System.out.println(fileData[i]);
content.append(fileData[i]).append("\n");
jTextPane1.setText(content.toString());
}
Also,
catch(Exception exep){}
is never a good idea. At least write:
catch(Exception exep) { exep.printStackTrace(); }
so you know what's going on when an excecption occurs.

Categories

Resources