Hello everyone and thanks for your help in advance. I am trying to use iText to merge all Pdf files contained within a directory. Here is my code:
public class MergeFiles
{
public MergeFiles(string targetDirectory) {
string dest = targetDirectory + #"\Merged.pdf";
PdfDocument pdfDoc = new PdfDocument(new PdfWriter(dest));
PdfMerger merger = new PdfMerger(pdfDoc);
string[] fileEntries = Directory.GetFiles(targetDirectory);
foreach (string fileName in fileEntries) {
//PdfMerger merger = new PdfMerger(pdfDoc);
PdfDocument newDoc = new PdfDocument(new PdfReader(fileName));
merger.Merge(newDoc, 1, newDoc.GetNumberOfPages());
newDoc.Close();
};
pdfDoc.Close();
}
}
This code is resulting in the error "System.IO.IOException: The process cannot access the file 'E:\Merged.pdf' because it is being used by another process." however, I am not sure why. Any help would be appreciated.
After these two lines:
string dest = targetDirectory + #"\Merged.pdf";
PdfDocument pdfDoc = new PdfDocument(new PdfWriter(dest));
A new (empty) file with name "Merged.pdf" is created in your target directory, with file stream opened in writing mode to write the result of the merging process.
Then, you are getting the list of file in target directory with string[] fileEntries = Directory.GetFiles(targetDirectory);. This array already includes your newly created Merged.pdf file.
Eventually the code tries to merge the resultant file into itself, which obviously fails.
To avoid this error, either collect the files to merge before creating the target document (but make sure there is no existing "Merged.pdf" file in the target directory already):
string[] fileEntries = Directory.GetFiles(targetDirectory);
string dest = targetDirectory + #"\Merged.pdf";
PdfDocument pdfDoc = new PdfDocument(new PdfWriter(dest));
// The rest of the code
Or, simply remove the target file from fileEntries array manually before merging the files.
Using itext7 and when trying to load XFA form I'm getting:
System.InvalidCastException: 'Unable to cast object of type
'System.Xml.Linq.XText' to type 'System.Xml.Linq.XElement'.'
Source code:
var pdfReader = new PdfReader(package.PdfTemplate);
pdfReader.SetUnethicalReading(true);
using (var document = new PdfDocument(pdfReader, new PdfWriter(writeMS)))
{
var acroForm = PdfAcroForm.GetAcroForm(document, true);
var xfa = acroForm.GetXfaForm();
var dataXml = _dataGenerator.GenerateXfaFormData(package);
xfa.FillXfaForm(dataXml);
xfa.Write(document);
}
The exception is thrown on line
var acroForm = PdfAcroForm.GetAcroForm(document, true);
Sample PDF can be seen here: https://programmcze-my.sharepoint.com/personal/nechanicky_programmcze_onmicrosoft_com/_layouts/15/guestaccess.aspx?docid=0c18710068a124a58a32e77ad53c4cbb9&authkey=AQvVBZLXNirrISLjvT083XY
There indeed was a problem with constructing XfaForm which does not contain <xfa:datasets> entry.
The problem is fixed in iText 7.0.5-SNAPSHOT version. The repository with the sources and the fix can be found here.
I'am creating Spring MVC web application.My image is in folder webapp/resources/img/logo.png of my MVC application.How to load image from that folder to pdf.
I tried with this code.But its trowing java.io.FileNotFoundException.
String imageUrl = "webapp/resources/img/logo.png"
logo = Image.getInstance(imageUrl);
Enhanced you find a example how I does it:
Document document = new Document();
PdfWriter.getInstance(document, new FileOutputStream("C:\\test.pdf"));
document.open();
Image img = Image.getInstance(ClassLoader.getSystemResource("attention-icon.jpg"));
img.scaleAbsolute(10, 10);
Phrase phrase = new Phrase();
phrase.add(new Chunk(img, 0,0));
document.add(new Paragraph(phrase));
document.close();
I think I your case the file "webapp/resources/img/logo.png" is to relativ. Try to create a File Object to check its location:
File logo = new File("webapp/resources/img/logo.png");
if(! logo.exists()){
LOG.warn("File " + logo.getName() + " not exists");
}
I had a PDF document and needed to add a couple of image fields. I imported the pdf file into Adobe LiveCycle as artwork. I then added my 2 images and saved as a static file. When I view the file using Adobe Reader, I can see the images. But when I try to merge the file with other static and dynamic pdf files created using LiveCycle, the images are missing.
I looked at the following thread
Images (imageField) are not shown after iText PDF Merging
but after checking the solution shown there against my code, I am already using PdfCopy instead of PdfWriter:
ByteArrayOutputStream output = new ByteArrayOutputStream();
PdfReader reader = new PdfReader(baosList.get(0).toByteArray());
Document document = new Document(reader.getPageSizeWithRotation(1));
reader.close();
PdfCopy writer = new PdfCopy(document, output);
document.open();
for (ByteArrayOutputStream baos : baosList)
{
// copy content
reader = new PdfReader(baos.toByteArray());
for (int idx = 1; idx <= reader.getNumberOfPages(); idx++)
writer.addPage(writer.getImportedPage(reader, idx));
reader.close();
baos.close();
}
I have other dynamic PDF files with images that are fine. I wonder if my problem is because I imported the original file as artwork.
I have an existing PDF and I can use FdFWriter to input to text boxes. It works well. Now I have an image. I have read the documentation and looked at many examples but they all create new documents and insert an image. I want to take an existing PDF and insert an image into either an image field or as the icon image of a button. I have tried but it corrupts the document.
I need to be able to take an existing document and put an image on it. I do not want to open, read, replace, and delete the original. This original changes and the name "original" only means the source file in this context. There are many PDF files like this that need an image.
Thank you for any help.
Edit - I am very thankful for the code below. It works great, but the problem for me is that the existing PDF has digital signatures on it. When the document is copied like this (into result.pdf) those signatures, while still present, have a different byte count or other item that is corrupted. This means the signatures, while they show up on result.pdf, have an icon next to them that state "invalid signature."
In case it matters I am using a Topaz signature pad to create my signatures, which has it's own security. Merely copying the PDF will not corrupt it but the process below will.
I am trying to put the image on the existing document, not a copy of it, which in this case matters.
Also, by signature, I mean handwritten, not pin numbers.
Thank you again.
EDIT - Can PdfSignatureAppearance be used for this?
EDIT - I seem to be able to do it with:
var stamper = new PdfStamper(reader, outputPdfStream,'1',true);
If you want to change the contents of an existing PDF file and add extra content such as watermarks, pagenumbers, extra headers, PdfStamper is the object you need. I have successfully used the following code to insert an image into an existing pdf file to a given absolute position:
using System.IO;
using iTextSharp.text;
using iTextSharp.text.pdf;
class Program
{
static void Main(string[] args)
{
using (Stream inputPdfStream = new FileStream("input.pdf", FileMode.Open, FileAccess.Read, FileShare.Read))
using (Stream inputImageStream = new FileStream("some_image.jpg", FileMode.Open, FileAccess.Read, FileShare.Read))
using (Stream outputPdfStream = new FileStream("result.pdf", FileMode.Create, FileAccess.Write, FileShare.None))
{
var reader = new PdfReader(inputPdfStream);
var stamper = new PdfStamper(reader, outputPdfStream);
var pdfContentByte = stamper.GetOverContent(1);
Image image = Image.GetInstance(inputImageStream);
image.SetAbsolutePosition(100, 100);
pdfContentByte.AddImage(image);
stamper.Close();
}
}
}
When you insert the image you have the possibility to resize it. You can take a look at transformation matrix in the iTextSharp documentation.
Here is a similar example whichi inserts an image on the page using the stamper:
Gmane iTex Mailing List Post
I could solve my problem by simply adding following lines to my signing code to add image
var image = iTextSharp.text.Image.GetInstance(#"C:\Users\sushil\Documents\sansign.jpg");
appearance.Acro6Layers = true;
appearance.SignatureGraphic = image;
appearance.SignatureRenderingMode = PdfSignatureAppearance.RenderingMode.GRAPHIC_AND_DESCRIPTION;
As I was signing document with visible digital signature , now I can have both image and digital signature properties side by side
in the .net core6 that uses DDD try this declare class in Infrastructure Layer
using System.IO;
using iTextSharp.text;
using iTextSharp.text.pdf;
public async Task<string> SignatureToPdf(string pathPdfFile, string
pathSignatureImage, string pathOutputName)
{
var webRootPath = hostingEnvironment.ContentRootPath;
if (!File.Exists(Path.Combine(webRootPath, pathPdfFile))) return
null;
await using Stream inputPdfStream =
new FileStream(Path.Combine(webRootPath, pathPdfFile),
FileMode.Open, FileAccess.Read, FileShare.Read);
await using Stream inputImageStream =
new FileStream(Path.Combine(webRootPath, pathSignatureImage), FileMode.Open, FileAccess.Read, FileShare.Read);
await using Stream outputPdfStream =
new FileStream(Path.Combine(webRootPath, pathOutputName),
FileMode.Create, FileAccess.Write, FileShare.None);
var reader = new PdfReader(inputPdfStream);
var stamper = new PdfStamper(reader, outputPdfStream);
var pdfContentByte = stamper.GetOverContent(1);
var image = Image.GetInstance(inputImageStream);
image.SetAbsolutePosition(100, 100);
pdfContentByte.AddImage(image);
stamper.Close();
return "ok";
}
pdftk can do this. It's not a library but you can easily call it from your code as a .exe.
See stamp and background commands:
http://www.pdflabs.com/docs/pdftk-man-page/
ref: How to do mail merge on top of a PDF?