How can I add PdfTable to an existing pdf document with iTextSharp - c#

Here is the way I open an existing pdf and add some values for the fields:
public static byte[] GeneratePdf(string pdfPath, Dictionary<string, string> formFieldMap)
{
var output = new MemoryStream();
var reader = new PdfReader(pdfPath);
var stamper = new PdfStamper(reader, output);
var formFields = stamper.AcroFields;
foreach (var fieldName in formFieldMap.Keys)
formFields.SetField(fieldName, formFieldMap[fieldName]);
stamper.FormFlattening = true;
stamper.Close();
reader.Close();
return output.ToArray();
}
Can you tell me how can I add a PdfTable object in this context?

Related

How to replace PDF field value by Image using iText7 in .NETCore

I've implemented it in iTextSharp but now i want to convert into iText7.
var pdfReader = new PdfReader(pdfPath1);
string outputfile = string.Empty;
var pdfStamper = new PdfStamper(pdfReader, new FileStream(newFile, FileMode.Create));
var pdfFormFields = pdfStamper.AcroFields;
outputfile = string.Empty;
if (!String.IsNullOrEmpty(sign1))
{
PushbuttonField pushbuttonField = pdfFormFields.GetNewPushbuttonFromField("imgSign1");
pushbuttonField.Layout = PushbuttonField.LAYOUT_ICON_ONLY;
pushbuttonField.ProportionalIcon = true;
pushbuttonField.Image = iTextSharp.text.Image.GetInstance(sign1);
pdfFormFields.ReplacePushbuttonField("imgSign1", pushbuttonField.Field);
}
i've tried to convert it but not getting proper way
var pdfReader = new PdfReader(pdfPath1);
var fstream = new FileStream(newFile, FileMode.Create);
var pdfwriter = new PdfWriter(fstream);
var document = new PdfDocument(pdfReader, pdfwriter);
var acroForm = PdfAcroForm.GetAcroForm(document, true);
outputfile = string.Empty;
if (!string.IsNullOrEmpty(sign1))
{
//what will be the alternative for PushbuttonField in iText7.
}

Copy into new document and fillout form in iText7 c#

I have been trying to get a grip of iText7 c# with little luck.
My goal is:
Load a pdf (one page) with a form (multiple fields) as a template
Fill out the form, Flatten and copy the filled forms page to a new document
repeat #2 x number of times with different data
Save to Memory Stream
I have the different parts working , but i cant get it to work together
var memoryStream = new MemoryStream();
PdfReader reader = new PdfReader("untitled-1.pdf"); //Iput
PdfWriter writer = new PdfWriter(memoryStream); //output
PdfDocument pdfDoc = new PdfDocument(reader, writer);
PdfAcroForm form = PdfAcroForm.GetAcroForm(pdfDoc, true);
var fields = form.GetFormFields();
if(fields.ContainsKey("address")) {
fields["address"].SetValue("first\nlast");
}
form.FlattenFields();
pdfDoc.Close();
byte[] b = memoryStream.ToArray();
File.WriteAllBytes(#"t.pdf", b);
clone page:
// create clone page x times
PdfDocument pdfDoc = new PdfDocument(new PdfWriter("output.pdf").SetSmartMode(true));
pdfDoc.InitializeOutlines();
PdfDocument srcDoc;
for (int i = 0; i<5; i++) {
srcDoc = new PdfDocument(new PdfReader("untitled-1.pdf"));
// copy content to the resulting PDF
srcDoc.CopyPagesTo(1, srcDoc.GetNumberOfPages(), pdfDoc);
}
pdfDoc.Close();
got an idea just after writing this question. Here is one solution to this problem
Create a pdf-file with a form and a text field named address to use as template, save as untitled1-pdf.
This code will create an empty document and then for each user in users load and fill the field address whit the user.
The filled form will then be flatten and copied into the new document.
When all is done, the document will be saved as result.pdf
//b.
static void Main(string[] args)
{
List<string> users = new List<string> { "Peter", "john", "Carl" };
byte[] result = createPdf(users, "untitled-1.pdf");
File.WriteAllBytes(#"result.pdf", result);
}
public static byte[] createPdf(List<string> users,string templateFile)
{
// create clone page for each user in users
using (MemoryStream memoryStream = new MemoryStream())
{
PdfDocument pdfDoc = new PdfDocument(new PdfWriter(memoryStream).SetSmartMode(true));
pdfDoc.InitializeOutlines();
PdfDocument srcDoc;
foreach (var u in users)
{
MemoryStream m = new MemoryStream(fillForm(u,templateFile));
srcDoc = new PdfDocument(new PdfReader(m));
// copy content to the resulting PDF
srcDoc.CopyPagesTo(1, srcDoc.GetNumberOfPages(), pdfDoc);
}
pdfDoc.Close();
return memoryStream.ToArray();
}
}
public static byte[] fillForm(string user,string templateFile)
{
using (var memoryStream = new MemoryStream())
{
PdfReader reader = new PdfReader(templateFile); //Iput
PdfWriter writer = new PdfWriter(memoryStream); //output
PdfDocument pdfDoc = new PdfDocument(reader, writer);
PdfAcroForm form = PdfAcroForm.GetAcroForm(pdfDoc, true);
var fields = form.GetFormFields();
if (fields.ContainsKey("address"))
{
fields["address"].SetValue(user);
}
form.FlattenFields();
pdfDoc.Close();
byte[] b = memoryStream.ToArray();
return b;
}
}

iTextSharp Fill Pdf Form Image Field

I created a pdf form with Acrobat DC 2015. I have a image field on it. I fill text field succesfully. But I don't know how to fill image field. Do you help me?
private static void FillPdfForm()
{
// Original File
const string pdfTemplate = #"pdf\form.pdf";
// New file which will be created after fillin PDF
var newFile = #"pdf\FilledCV.PDF";
var pdfReader = new PdfReader(pdfTemplate);
var pdfStamper = new PdfStamper(pdfReader, new FileStream(
newFile, FileMode.Create));
var pdfFormFields = pdfStamper.AcroFields;
// So one of our fields in PDF is FullName I am filling it with my full name
pdfFormFields.SetFieldProperty("01", "textsize", 8f, null);
pdfFormFields.SetField("01", "Example");
// flatten the form to remove editting options, set it to false
// to leave the form open to subsequent manual edits
foreach (var de in pdfReader.AcroFields.Fields)
{
pdfFormFields.SetFieldProperty(de.Key.ToString(),
"setfflags",
PdfFormField.FF_READ_ONLY,
null);
}
pdfStamper.FormFlattening = false;
pdfStamper.FormFlattening = false;
pdfStamper.Close();
}
I fixed it.
private static void FillPdfForm()
{
const string pdfTemplate = #"pdf\form.pdf";
var newFile = #"pdf\FilledCV.PDF";
var pdfReader = new PdfReader(pdfTemplate);
var pdfStamper = new PdfStamper(pdfReader, new FileStream(newFile, FileMode.Create));
var pdfFormFields = pdfStamper.AcroFields;
string TestImage = #"pdf\test.jpg";
PushbuttonField ad = pdfFormFields.GetNewPushbuttonFromField("08");
ad.Layout = PushbuttonField.LAYOUT_ICON_ONLY;
ad.ProportionalIcon = true;
ad.Image = Image.GetInstance(TestImage);
pdfFormFields.ReplacePushbuttonField("08", ad.Field);
pdfFormFields.SetFieldProperty("01", "textsize", 8f, null);
pdfFormFields.SetField("01", "Example");
foreach (var de in pdfReader.AcroFields.Fields)
{
pdfFormFields.SetFieldProperty(de.Key,"setfflags",PdfFormField.FF_READ_ONLY,null);
}
pdfStamper.FormFlattening = false;
pdfStamper.Close();
}

iText7 Create PDF in memory instead of physical file

How do one create PDF in memorystream instead of physical file using itext7?
I have no idea how to do it in the latest version, any help?
I tried the following code, but pdfSM is not properly populated:
string filePath = "./abc.pdf";
MemoryStream pdfSM = new ByteArrayOutputStream();
PdfDocument doc = new PdfDocument(new PdfReader(filePath), new PdfWriter(pdfSM));
.......
doc.close();
The full testing code as below for your reference, it worked when past filePath into PdfWriter but not for the memory stream:
public static readonly String sourceFolder = "../../FormTest/";
public static readonly String destinationFolder = "../../Output/";
static void Main(string[] args)
{
String srcFilePattern = "I-983";
String destPattern = "I-129_2014_";
String src = sourceFolder + srcFilePattern + ".pdf";
String dest = destinationFolder + destPattern + "_flattened.pdf";
MemoryStream returnSM = new MemoryStream();
PdfDocument doc = new PdfDocument(new PdfReader(src), new PdfWriter(returnSM));
PdfAcroForm form = PdfAcroForm.GetAcroForm(doc, false);
foreach (PdfFormField field in form.GetFormFields().Values)
{
var fieldName = field.GetFieldName();
var type = field.GetType();
if (fieldName != null)
{
if (type.Name.Equals("PdfTextFormField"))
{
field.SetValue("T");
}
}
}
form.FlattenFields();
doc.Close();
}
This works for me.
public byte[] CreatePdf()
{
var stream = new MemoryStream();
var writer = new PdfWriter(stream);
var pdf = new PdfDocument(writer);
var document = new Document(pdf);
document.Add(new Paragraph("Hello world!"));
document.Close();
return stream.ToArray();
}
I needed the same thing. Got it working like this:
(I included some settings which improve performance)
string HtmlString = "<html><head></head><body>some content</body></html>";
byte[] buffer;
PdfDocument pdfDoc = null;
using (MemoryStream memStream = new MemoryStream())
{
using(PdfWriter pdfWriter = new PdfWriter(memStream, wp))
{
pdfWriter.SetCloseStream(true);
using (pdfDoc = new PdfDocument(pdfWriter))
{
ConverterProperties props = new ConverterProperties();
pdfDoc.SetDefaultPageSize(PageSize.LETTER);
pdfDoc.SetCloseWriter(true);
pdfDoc.SetCloseReader(true);
pdfDoc.SetFlushUnusedObjects(true);
HtmlConverter.ConvertToPdf(HtmlString, pdfDoc, props));
pdfDoc.Close();
}
}
buffer = memStream.ToArray();
}
return buffer;
iText7、C# Controller
Error:
public ActionResult Report()
{
//...
doc1.Close();
return File(memoryStream1, "application/pdf", "pdf_file_name.pdf");
}
Work:
public ActionResult Report()
{
//...
doc1.Close();
byte[] byte1 = memoryStream1.ToArray();
return File(byte1, "application/pdf", "pdf_file_name.pdf");
}
I don't know why... but, it's working!
another: link

Itext Sharp Merge Pdfs with acrofields

I'm using itext sharp to fill my form fields on my template with values.
I created the template using pdfescape.com
Here is my code that I use to place the values in the pdf template.
private static byte[] GeneratePdf(Dictionary<String, String> formKeys, String pdfPath)
{
var templatePath = System.Web.HttpContext.Current.Server.MapPath(pdfPath);
var reader = new PdfReader(templatePath);
var outStream = new MemoryStream();
var stamper = new PdfStamper(reader, outStream);
var form = stamper.AcroFields;
var fieldKeys = form.Fields.Keys;
// "Flatten" the form so it wont be editable/usable anymore
// stamper.FormFlattening = true;
foreach (KeyValuePair<String, String> pair in formKeys)
{
if (fieldKeys.Any(f => f == pair.Key))
{
form.SetField(pair.Key, pair.Value);
form.SetFieldProperty(pair.Key, "setfflags", PdfFormField.FF_READ_ONLY, null);
}
}
stamper.Close();
reader.Close();
return outStream.ToArray();
}
I first used the stamper.FormFlattening = true, but then the values weren't visible. So Instead of using the form flattening I just set the values as ready only and everything works fine.
Now I want to merge multiple of these pdf files using the the pdf merger by smart-soft
Once the merging is complete the values aren't visible. When I highlight over the form it highlights all the text, but I can't read it.I did research on this and read that the fields need to be flattened.
Here is an image of how it looks on the pdf when I highlight everything:
I don't know why my fields aren't visible when they are flattened, even if I don't use the merger. Is there something wrong with the code or the template? Alternatives will also be appreciated.
Btw my project is an asp-mvc project if that is relevant.
EDIT
I added the following code so that I first read the template, write the values to the form fields, close it, reopen it, flatten and then close it again as suggested by one of the comments. I just pass the result I get from the GeneratePdf function to this function:
private static byte[] flattenPdf(byte[] pdf)
{
var reader = new PdfReader(pdf);
var outStream = new MemoryStream();
var stamper = new PdfStamper(reader, outStream);
stamper.FormFlattening = true;
stamper.Close();
reader.Close();
return outStream.ToArray();
}
I still get the same result
I found a solution to this problem thanks to this answer by rhens
All I had to do is modify my GeneratePdf function by adding one line:
form.GenerateAppearances = true;
Here is the end result:
private static byte[] GeneratePdf(Dictionary<String, String> formKeys, String pdfPath)
{
var templatePath = System.Web.HttpContext.Current.Server.MapPath(pdfPath);
var reader = new PdfReader(templatePath);
var outStream = new MemoryStream();
var stamper = new PdfStamper(reader, outStream);
var form = stamper.AcroFields;
form.GenerateAppearances = true; //Added this line, fixed my problem
var fieldKeys = form.Fields.Keys;
foreach (KeyValuePair<String, String> pair in formKeys)
{
if (fieldKeys.Any(f => f == pair.Key))
{
form.SetField(pair.Key, pair.Value);
}
}
stamper.Close();
reader.Close();
return flattenPdf(outStream.ToArray());
}
and the flattenPdf stays the same as in my question.

Categories