How to merge multiple PDF/A files and generate new PDF/A in java - itext

I want to merge multiple PDF/A files and generated a new PDF/A file using java. I tried it with OpenPDF using PdfCopy class but it produced pdf document which does not conform to the PDF/A-1a standard.
Also tried with pdf-box and aspose-pdf library but did not work. Those are also producing normal PDF instead of PDF/A.
Getting following output with online pdf checker (https://www.pdf-online.com/osa/validate.aspx):
File: mergeusing_openPDF.pdf
Compliance: pdfa-1a
Result:
Document does not conform to PDF/A.
Details:
Validating file "mergeusing_openPDF.pdf" for conformance level pdfa-1a
The key MarkInfo is required but missing.
The key StructTreeRoot is required but missing.
The document does not conform to the requested standard.
The document doesn't provide appropriate logical structure information.
The document does not conform to the PDF/A-1a standard.
Done.
Posting a part of code of OpenPDF:
import java.awt.color.ICC_Profile;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import com.lowagie.text.Document;
import com.lowagie.text.pdf.PdfCopy;
import com.lowagie.text.pdf.PdfImportedPage;
import com.lowagie.text.pdf.PdfReader;
import com.lowagie.text.pdf.PdfWriter;
public class ExampleMerge {
public static void main(String args[]) throws IOException {
List<String> pdfAFilesToMerge = Arrays.asList("D:/file1.pdf", "D:/file2.pdf");
String newFilePath = "D:/merge_using_openPDF.pdf";
PdfReader pdfReader = new PdfReader(pdfAFilesToMerge.get(0));
Document document = new Document(pdfReader.getPageSizeWithRotation(1));
PdfCopy copy = new PdfCopy(document, new FileOutputStream(newFilePath));
copy.setTagged();
copy.setPDFXConformance(PdfWriter.PDFA1A);
copy.createXmpMetadata();
document.open();
String iccProfilePath = "C:/ICC_Profiles/sRGB_IEC61966-2-1.icc";
ICC_Profile icc;
try {
icc = ICC_Profile.getInstance(new FileInputStream(iccProfilePath));
copy.setOutputIntents("Custom", "", "http://www.color.org", "sRGB IEC61966-2.1", icc);
} catch (IOException e) {
e.printStackTrace();
}
for (int i = 0; i < pdfAFilesToMerge.size(); i++) {
for (int j = 1; j <= pdfReader.getNumberOfPages(); j++) {
PdfImportedPage page = copy.getImportedPage(pdfReader, j);
copy.addPage(page);
}
if (i + 1 < pdfAFilesToMerge.size())
pdfReader = new PdfReader(pdfAFilesToMerge.get(i + 1));
}
document.close();
System.out.println("Documents merged");
}
}

Related

Adding file to GitHub using java client - org.eclipse.egit.github.core

I am trying to add a file to a repository using the below code but I am getting below error. I just want to add a file for now.
org.eclipse.egit.github.core.client.RequestException: Invalid request.
For 'properties/email', nil is not a string. For 'properties/name',
nil is not a string. For 'properties/email', nil is not a string. For
'properties/name', nil is not a string. (422) at
org.eclipse.egit.github.core.client.GitHubClient.createException(GitHubClient.java:552)
at
org.eclipse.egit.github.core.client.GitHubClient.sendJson(GitHubClient.java:643)
at
org.eclipse.egit.github.core.client.GitHubClient.post(GitHubClient.java:757)
at
org.eclipse.egit.github.core.service.DataService.createCommit(DataService.java:397)
I sense that it is expecting some properties but how to supply this is not clear. What is that i am missing?
Referring to https://gist.github.com/Detelca/2337731
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import org.eclipse.egit.github.core.Blob;
import org.eclipse.egit.github.core.Commit;
import org.eclipse.egit.github.core.CommitUser;
import org.eclipse.egit.github.core.Reference;
import org.eclipse.egit.github.core.Repository;
import org.eclipse.egit.github.core.RepositoryCommit;
import org.eclipse.egit.github.core.Tree;
import org.eclipse.egit.github.core.TreeEntry;
import org.eclipse.egit.github.core.TypedResource;
import org.eclipse.egit.github.core.User;
import org.eclipse.egit.github.core.client.GitHubClient;
import org.eclipse.egit.github.core.service.CommitService;
import org.eclipse.egit.github.core.service.DataService;
import org.eclipse.egit.github.core.service.RepositoryService;
import org.eclipse.egit.github.core.service.UserService;
public class GHWriter {
public static void main(String[] args) {
try {
new GHWriter().writeFile("test_two.txt", "test content");
} catch (IOException e) {
e.printStackTrace();
}
}
//https://gist.github.com/Detelca/2337731
public boolean writeFile(String fileName, String fileContent) throws IOException{
// initialize github client
GitHubClient client = new GitHubClient();
//TextView password = (TextView)findViewById(R.id.textViewPassword);
client.setCredentials("username", "password");
// create needed services
RepositoryService repositoryService = new RepositoryService();
CommitService commitService = new CommitService(client);
DataService dataService = new DataService(client);
// get some sha's from current state in git
Repository repository = repositoryService.getRepository("username", "repositoryName");
String baseCommitSha = repositoryService.getBranches(repository).get(0).getCommit().getSha();
RepositoryCommit baseCommit = commitService.getCommit(repository, baseCommitSha);
String treeSha = baseCommit.getSha();
// create new blob with data
Blob blob = new Blob();
blob.setContent("[\"" + System.currentTimeMillis() + "\"]").setEncoding(Blob.ENCODING_UTF8);
String blob_sha = dataService.createBlob(repository, blob);
Tree baseTree = dataService.getTree(repository, treeSha);
// create new tree entry
TreeEntry treeEntry = new TreeEntry();
treeEntry.setPath("testfile.txt");
treeEntry.setMode(TreeEntry.MODE_BLOB);
treeEntry.setType(TreeEntry.TYPE_BLOB);
treeEntry.setSha(blob_sha);
treeEntry.setSize(blob.getContent().length());
Collection<TreeEntry> entries = new ArrayList<TreeEntry>();
entries.add(treeEntry);
Tree newTree = dataService.createTree(repository, entries, baseTree.getSha());
// create commit
Commit commit = new Commit();
commit.setMessage("first commit at " + new Date(System.currentTimeMillis()).toLocaleString());
commit.setTree(newTree);
UserService userService = new UserService( client );
User user = userService.getUser();
CommitUser author = new CommitUser();
author.setName( user.getName() );
Calendar now = Calendar.getInstance();
author.setDate(now.getTime());
commit.setAuthor(author);
commit.setCommitter(author);
List<Commit> listOfCommits = new ArrayList<Commit>();
listOfCommits.add(new Commit().setSha(baseCommitSha));
// listOfCommits.containsAll(base_commit.getParents());
commit.setParents(listOfCommits);
// commit.setSha(base_commit.getSha());
Commit newCommit = dataService.createCommit(repository, commit);
// create resource
TypedResource commitResource = new TypedResource();
commitResource.setSha(newCommit.getSha());
commitResource.setType(TypedResource.TYPE_COMMIT);
commitResource.setUrl(newCommit.getUrl());
// get master reference and update it
Reference reference = dataService.getReference(repository, "heads/master");
reference.setObject(commitResource);
dataService.editReference(repository, reference, true);
System.out.println("Committed URL: "+ newCommit.getUrl());
return false;
}
}
Thanks
After some debugging, found that email and name values are coming as null which is the source of the issue.
Adding below two lines will solve the issue:
author.setName( userName );
author.setEmail(email);

PdfContentByte.addTemplate(pdfImportedPage, 0, 0) behaves strangly. Upper text truncated [duplicate]

I have the following problem when printing the pdf file after merge, the pdf documents get cut off.
Sometimes this happens because the documents aren't 8.5 x 11
they might be like 11 x 17.
Can we make it detect the page size and then use that same page size for those documents?
Or, if not, is it possible to have it fit to page?
Following is the code:
package com.sumit.program;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import com.itextpdf.text.Document;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfImportedPage;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfWriter;
public class MergePdf {
public static void main(String[] args) {
try {
List<InputStream> pdfs = new ArrayList<InputStream>();
pdfs.add(new FileInputStream("C:\\Documents and Settings\\Sumit\\Desktop\\NewEcnProject\\Document1.pdf"));
pdfs.add(new FileInputStream("C:\\Documents and Settings\\Sumit\\Desktop\\NewEcnProject\\Landscape.pdf"));
OutputStream output = new FileOutputStream("C:\\Documents and Settings\\Sumit\\Desktop\\NewEcnProject\\merge1.pdf");
MergePdf.concatPDFs(pdfs, output, true);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void concatPDFs(List<InputStream> streamOfPDFFiles,
OutputStream outputStream, boolean paginate) {
Document document = new Document();
try {
List<InputStream> pdfs = streamOfPDFFiles;
List<PdfReader> readers = new ArrayList<PdfReader>();
int totalPages = 0;
Iterator<InputStream> iteratorPDFs = pdfs.iterator();
// Create Readers for the pdfs.
int i=1;
while (iteratorPDFs.hasNext()) {
InputStream pdf = iteratorPDFs.next();
PdfReader pdfReader = new PdfReader(pdf);
System.out.println("Page size is "+pdfReader.getPageSize(1));
readers.add(pdfReader);
totalPages += pdfReader.getNumberOfPages();
i++;
}
// Create a writer for the outputstream
PdfWriter writer = PdfWriter.getInstance(document, outputStream);
writer.setCompressionLevel(9);
document.open();
BaseFont bf = BaseFont.createFont(BaseFont.HELVETICA,
BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
PdfContentByte cb = writer.getDirectContent(); // Holds the PDF data
PdfImportedPage page;
int currentPageNumber = 0;
int pageOfCurrentReaderPDF = 0;
Iterator<PdfReader> iteratorPDFReader = readers.iterator();
// Loop through the PDF files and add to the output.
while (iteratorPDFReader.hasNext()) {
PdfReader pdfReader = iteratorPDFReader.next();
// Create a new page in the target for each source page.
System.out.println("No. of pages "+pdfReader.getNumberOfPages());
i=0;
while (pageOfCurrentReaderPDF < pdfReader.getNumberOfPages()) {
Rectangle r=pdfReader.getPageSize(pdfReader.getPageN(pageOfCurrentReaderPDF+1));
if(r.getWidth()==792.0 && r.getHeight()==612.0)
document.setPageSize(PageSize.A4.rotate());
else
document.setPageSize(PageSize.A4);
document.newPage();
pageOfCurrentReaderPDF++;
currentPageNumber++;
i++;
page = writer.getImportedPage(pdfReader,
pageOfCurrentReaderPDF);
System.out.println("Width is "+page.getWidth());
System.out.println("Height is "+page.getHeight());
cb.newlineText();
cb.addTemplate(page, 0, 0);
// Code for pagination.
if (paginate) {
cb.beginText();
cb.setFontAndSize(bf, 9);
cb.showTextAligned(PdfContentByte.ALIGN_CENTER, ""
+ currentPageNumber + " of " + totalPages, 520,
5, 0);
cb.endText();
}
}
pageOfCurrentReaderPDF = 0;
}
outputStream.flush();
document.close();
outputStream.close();
System.out.println("Merging of Pdfs is done.......");
} catch (Exception e) {
e.printStackTrace();
} finally {
if (document.isOpen())
document.close();
try {
if (outputStream != null)
outputStream.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
}
Using the Document and PdfWriter class in combination with the addTemplate() method to merge documents is a bad idea. That's not what the addTemplate() method is meant for. You have explicitly or implicitly defined the page size for the Document you are working with. With the addTemplate() method, you add PdfImportedPage instances, and
when you add a new page with the same page size and rotation, you throw away all interactivity that exists in that page, but otherwise all is well,
when you add a new page with a different page size and rotation, you get the result you describe. Because of the difference in size, the imported page and the new page do not match. Parts get cut off, extra margins appear, rotations are different, etc.
This is all explained in chapter 6 of my book. You should use PdfCopy instead of PdfWriter. See for instance the FillFlattenMerge2 example:
Document document = new Document();
PdfCopy copy = new PdfSmartCopy(document, new FileOutputStream(dest));
document.open();
PdfReader reader;
String line = br.readLine();
// loop over readers
// add the PDF to PdfCopy
reader = new PdfReader(baos.toByteArray());
copy.addDocument(reader);
reader.close();
// end loop
document.close();
In your case, you also need to add page numbers, you can do this in a second go, as is done in the StampPageXofY example:
PdfReader reader = new PdfReader(src);
int n = reader.getNumberOfPages();
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
PdfContentByte pagecontent;
for (int i = 0; i < n; ) {
pagecontent = stamper.getOverContent(++i);
ColumnText.showTextAligned(pagecontent, Element.ALIGN_RIGHT,
new Phrase(String.format("page %s of %s", i, n)), 559, 806, 0);
}
stamper.close();
reader.close();
Or you can add them while merging, as is done in the MergeWithToc example.
Document document = new Document();
PdfCopy copy = new PdfCopy(document, new FileOutputStream(filename));
PageStamp stamp;
document.open();
int n;
int pageNo = 0;
PdfImportedPage page;
Chunk chunk;
for (Map.Entry<String, PdfReader> entry : filesToMerge.entrySet()) {
n = entry.getValue().getNumberOfPages();
for (int i = 0; i < n; ) {
pageNo++;
page = copy.getImportedPage(entry.getValue(), ++i);
stamp = copy.createPageStamp(page);
chunk = new Chunk(String.format("Page %d", pageNo));
if (i == 1)
chunk.setLocalDestination("p" + pageNo);
ColumnText.showTextAligned(stamp.getUnderContent(),
Element.ALIGN_RIGHT, new Phrase(chunk),
559, 810, 0);
stamp.alterContents();
copy.addPage(page);
}
}
document.close();
for (PdfReader r : filesToMerge.values()) {
r.close();
}
reader.close();
I strongly advise against using PdfWriter to merge documents! It's not impossible if you change the page size and the rotation of the page in the Document class, but you're making it harder on yourself. Moreover: using PdfWriter also throws away all interactivity (links, annotations,...) that exists in the pages you're merging. Your customer may experience that as a bug.

JMapframe displays only a single shapefile

I used the Netbeans and GeoTools to program a graphical interface to display multiple shapefiles in the same JmapFrame. I used the following code but I do not know, when execute, it display only one shapefile.Svp, someone can help me, I await your answers.
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry;
import java.io.File;
import org.geotools.data.FeatureSource;
import org.geotools.data.FileDataStore;
import org.geotools.data.FileDataStoreFinder;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.map.DefaultMapContext;
import org.geotools.map.MapContext;
import org.geotools.swing.JMapFrame;
import org.geotools.swing.data.JFileDataStoreChooser;
import org.opengis.feature.simple.SimpleFeature;
/**
*
* #author Brahim
*/
class ImportVecteur2
{
private JMapFrame fenMap;
private MapContext mapContext;
ImportVecteur2(JMapFrame fenMap)
{
//this.mapContext = mapContext;
this.fenMap = fenMap;
}
#SuppressWarnings("static-access")
public void chercheAfficheVecteur() //throws Exception
{
try
{
File file = JFileDataStoreChooser.showOpenFile("shp", null);
if (file == null)
{
return;
}
FileDataStore store = FileDataStoreFinder.getDataStore(file);
FeatureSource featureSource = store.getFeatureSource();
//get vertices of file
// Create a map context and add our shapefile to it
mapContext = new DefaultMapContext();
mapContext.addLayer(featureSource, null);
// Now display the map
fenMap.enableLayerTable(true);
fenMap.setMapContext(mapContext);
fenMap.setVisible(true);
}
Each time you call chercheAfficheVecteur you create a new MapContext so the previous one is thrown away and with it your previous shapefile. If you change the method to be
public void chercheAfficheVecteur() {
try {
File file = JFileDataStoreChooser.showOpenFile("shp", null);
if (file == null) {
return;
}
FileDataStore store = FileDataStoreFinder.getDataStore(file);
FeatureSource featureSource = store.getFeatureSource();
//get vertices of file
// Create a map context and add our shapefile to it
if(mapContext == null){
mapContext = new DefaultMapContext();
fenMap.setMapContext(mapContext);
}
//make it look prettier
Style style = SLD.createSimpleStyle(featureSource.getSchema());
mapContext.addLayer(featureSource, style);
}
and
ImportVecteur2(JMapFrame fenMap)
{
//this.mapContext = mapContext;
this.fenMap = fenMap;
fenMap.enableLayerTable(true);
fenMap.setVisible(true);
}
It should work better.
After further testing (i.e. I actually compiled some code) - MapContext is deprecated (and has been for some time) please use MapContent.
package org.geotools.tutorial.quickstart;
import java.awt.Color;
import java.awt.Dimension;
import java.io.File;
import java.io.IOException;
import org.geotools.data.FeatureSource;
import org.geotools.data.FileDataStore;
import org.geotools.data.FileDataStoreFinder;
import org.geotools.map.FeatureLayer;
import org.geotools.map.Layer;
import org.geotools.map.MapContent;
import org.geotools.styling.SLD;
import org.geotools.styling.Style;
import org.geotools.swing.JMapFrame;
import org.geotools.swing.data.JFileDataStoreChooser;
public class Test {
private static final Color[] color = { Color.red, Color.blue, Color.green,
Color.MAGENTA };
private static MapContent mapContext;
private static JMapFrame fenMap;
public static void main(String args[]) throws IOException {
Test me = new Test();
me.run();
}
public void run() throws IOException {
fenMap = new JMapFrame();
mapContext = new MapContent();
fenMap.setMapContent(mapContext);
fenMap.enableToolBar(true);
fenMap.setMinimumSize(new Dimension(300, 300));
fenMap.setVisible(true);
int i = 0;
while (chercheAfficheVecteur(i)) {
i++;
i = i % color.length;
}
}
public boolean chercheAfficheVecteur(int next) throws IOException {
File file = JFileDataStoreChooser.showOpenFile("shp", null);
if (file == null) {
return false;
}
FileDataStore store = FileDataStoreFinder.getDataStore(file);
FeatureSource featureSource = store.getFeatureSource();
// get vertices of file
// Create a map context and add our shapefile to it
if (mapContext == null) {
}
// make it look prettier
Style style = SLD.createSimpleStyle(featureSource.getSchema(), color[next]);
Layer layer = new FeatureLayer(featureSource, style);
mapContext.addLayer(layer);
return true;
}
}

iText - Convert field names with square brackets to fields without square brackets?

import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.PdfStamper;
import java.util.Set;
import java.io.FileOutputStream;
public class PDFFile {
public static final String xfaForm3 = "C:/PDF_Service/pdf-project/src/sample.pdf";
public static final String dest = "sample2.xml";
public static void main(String[] args)
{
PdfReader reader;
PdfReader.unethicalreading = true;
AcroFields form;
try{
reader = new PdfReader(xfaForm3);
PdfStamper stamper2 = new PdfStamper(reader, new FileOutputStream(dest));
form = stamper2.getAcroFields();
stamper2.close();
Set<String> fldNames = form.getFields().keySet();
for (String fldName : fldNames)
{
System.out.println( fldName + " : " + form.getField( fldName ) );
}
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
My code above is reading a PDF file that has the XFA format and it prints out something that looks like this:
F[0].P1[0].FFField1[14] : 11 Pine Drive
Instead of printing out "F[0].P1[0].FFField1[14]", how can I print out "Address"?
I would like my code to print out this:
Address : 11 Pine Drive

i text jsp output to pdf [duplicate]

This question already has answers here:
iText - generating files on the fly without needing a PDF file
(3 answers)
Closed 6 years ago.
i m trying to use the itext to convert the jsp output to pdf format
using itext and i dnt have much knowledge in java i m just starting the
programming please help me to convert the jsp output to pdf
i had tried some one example but its converting the jsp code to pdf but not the jsp out put
here is my code
import com.lowagie.text.Document;
import com.lowagie.text.Paragraph;
import com.lowagie.text.Rectangle;
import com.lowagie.text.pdf.PdfWriter;
import java.io.File;
import java.io.FileOutputStream;
public class PDFConversion
{
private void createPdf(String inputFile, String outputFile, boolean isPictureFile)
{
Rectangle pageSize = new Rectangle(2780, 2525);
Document pdfDocument = new Document(pageSize);
String pdfFilePath = "C:\\Users\\hp\\Desktop\\jsp_to_pdf.pdf";
try
{
FileOutputStream fileOutputStream = new FileOutputStream(pdfFilePath);
//PdfWriter writer = null;
PdfWriter writer = PdfWriter.getInstance(pdfDocument, fileOutputStream);
writer.open();
pdfDocument.open();
if (isPictureFile)
{
pdfDocument.add(com.lowagie.text.Image.getInstance("C:\\Users\\hp\\Documents\\NetBeansProjects\\pdf_print\\web\\example1.jsp"));
}
else
{
File file = new File("C:\\Users\\hp\\Documents\\NetBeansProjects\\pdf_print\\web\\example1.jsp");
pdfDocument.add(new Paragraph(org.apache.commons.io.FileUtils.readFileToString(file)));
}
pdfDocument.close();
writer.close();
}
catch (Exception exception)
{
System.out.println("Document Exception!" + exception);
}
}
public static void main(String args[])
{
PDFConversion pdfConversion = new PDFConversion();
pdfConversion.createPdf("example1.jsp","jsp_to_pdf.pdf", false);
}
}
thanks&regards
shadab akram khan
If you want to provide a feature of downloading PDF, get the content as byte[], and do the following:
response.setHeader("Content-Disposition", "attachment; filename=\"application.pdf\"");
response.setHeader("Pragma", "public");
response.setDateHeader("Expires", 0);
response.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");
response.setHeader("Cache-Control", "public");
response.setHeader("Content-Description", "File Transfer");
response.setContentType("application/pdf");
response.getOutputStream().write(pdfBytes);