Using c# and iText7 I need to modify an existing PDF and save it to blob storage.
I have a console app that does exactly what I need using the file system:
PdfReader reader = new PdfReader(source);
PdfWriter writer = new PdfWriter(destination2);
PdfDocument pdfDoc = new PdfDocument(reader, writer);
PdfAcroForm form = PdfAcroForm.GetAcroForm(pdfDoc, true);
fields = form.GetFormFields();
fields.TryGetValue("header", out PdfFormField cl);
var type = cl.GetType();
cl.SetValue("This is a header");
pdfDoc.Close();
This works just fine. However I can not figure out how to do the same thing pulling the PDF from blob storage and sending the new one to blob storage
IDictionary<string, PdfFormField> fields;
MemoryStream outStream = new MemoryStream();
var pdfTemplate = _blobStorageService.GetBlob("mycontainer", "TestPDF.pdf");
PdfReader reader = new PdfReader(pdfTemplate);
PdfWriter writer = new PdfWriter(outStream);
PdfDocument pdfDoc = new PdfDocument(reader, writer);
PdfAcroForm form = PdfAcroForm.GetAcroForm(pdfDoc, true);
fields = form.GetFormFields();
fields.TryGetValue("header", out PdfFormField cl);
cl.SetValue("This is a header");
pdfDoc.Close();
outStream.Position = 0;
_blobStorageService.UploadBlobAsync("mycontainer", **THIS IS THE ISSUE**, "newpdf.pdf");
I think I need to get pdfDoc as a byte array. Outstream is incorrect, it is only has a length of 15
The code below shows how to read a PDF from a file into a byte[] and also how to modify a PDF that's stored as a byte[].
Download and install NuGet package: iText7
In Solution Explorer, right-click <project name> and select Manage NuGet Packages...
Click Browse
In the search box type: iText7
Select iText7
Select desired version
Click Install
Add the following using statements:
using System.IO;
using iText.Kernel.Pdf;
using iText.Forms;
using iText.Forms.Fields;
Get PDF as byte[] (GetPdfBytes):
public static Task<byte[]> GetPdfBytes(string pdfFilename)
{
byte[] pdfBytes = null;
using (PdfReader reader = new PdfReader(pdfFilename))
{
using (MemoryStream msPdfWriter = new MemoryStream())
{
using (PdfWriter writer = new PdfWriter(msPdfWriter))
{
using (PdfDocument pdfDoc = new PdfDocument(reader, writer))
{
//don't close underlying streams when PdfDocument is closed
pdfDoc.SetCloseReader(false);
pdfDoc.SetCloseWriter(false);
//close
pdfDoc.Close();
//set value
msPdfWriter.Position = 0;
//convert to byte[]
pdfBytes = msPdfWriter.ToArray();
}
}
}
}
return Task.FromResult(pdfBytes);
}
Usage:
byte[] pdfBytes = null;
string filename = string.Empty;
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "PDF File (*.pdf)|*.pdf";
if (ofd.ShowDialog() == DialogResult.OK)
{
//get PDF as byte[]
var tResult = GetPdfBytes(ofd.FileName);
pdfBytes = tResult.Result;
//For testing, write back to file so we can ensure that the PDF file opens properly
//create a new filename
filename = System.IO.Path.GetFileNameWithoutExtension(ofd.FileName) + " - Test.pdf";
filename = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(ofd.FileName), filename);
//save to file
File.WriteAllBytes(filename, pdfBytes);
System.Diagnostics.Debug.WriteLine("Saved as '" + filename + "'");
}
Modify PDF that's stored in a byte[] (ModifyPdf)
public static Task<byte[]> ModifyPdf(byte[] pdfBytes)
{
byte[] modifiedPdfBytes = null;
using (MemoryStream ms = new MemoryStream(pdfBytes))
{
using (PdfReader reader = new PdfReader(ms))
{
using (MemoryStream msPdfWriter = new MemoryStream())
{
using (PdfWriter writer = new PdfWriter(msPdfWriter))
{
using (PdfDocument pdfDoc = new PdfDocument(reader, writer))
{
//don't close underlying streams when PdfDocument is closed
pdfDoc.SetCloseReader(false);
pdfDoc.SetCloseWriter(false);
//get AcroForm from document
PdfAcroForm form = PdfAcroForm.GetAcroForm(pdfDoc, true);
//get form fields
IDictionary<string, PdfFormField> fields = form.GetFormFields();
//for testing, show all fields
foreach (KeyValuePair<string, PdfFormField> kvp in fields)
{
System.Diagnostics.Debug.WriteLine("Key: '" + kvp.Key + "' Value: '" + kvp.Value + "'");
}
PdfFormField cl = null;
//get specified field
fields.TryGetValue("1 Employee name", out cl);
//set value for specified field
cl.SetValue("John Doe");
//close PdfDocument
pdfDoc.Close();
//set value
msPdfWriter.Position = 0;
//convert to byte[]
modifiedPdfBytes = msPdfWriter.ToArray();
}
}
}
}
}
return Task.FromResult(modifiedPdfBytes);
}
Usage:
byte[] pdfBytes = null;
string filename = string.Empty;
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "PDF File (*.pdf)|*.pdf";
if (ofd.ShowDialog() == DialogResult.OK)
{
//get PDF as byte[]
var tResult = GetPdfBytes(ofd.FileName);
pdfBytes = tResult.Result;
//modify PDF
pdfBytes = await ModifyPdf(pdfBytes);
//create a new filename
filename = System.IO.Path.GetFileNameWithoutExtension(ofd.FileName) + " - TestModified.pdf";
filename = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(ofd.FileName), filename);
//save to file
File.WriteAllBytes(filename, pdfBytes);
System.Diagnostics.Debug.WriteLine("Saved as '" + filename + "'");
}
The code below is adapted from Sample01b_HelloWorldAsync.cs and is untested.
Download and install NuGet package: Azure.Storage.Blobs
Add the following using statement:
using Azure.Storage.Blobs;
DownloadPdf:
public static async Task<byte[]> DownloadPdf(string connectionString, string blobContainerName, string blobName)
{
byte[] pdfBytes = null;
using (MemoryStream ms = new MemoryStream())
{
// Get a reference to the container and then create it
BlobContainerClient container = new BlobContainerClient(connectionString, blobContainerName);
Azure.Response<Azure.Storage.Blobs.Models.BlobContainerInfo> responseCA = await container.CreateAsync();
// Get a reference to the blob
BlobClient blob = container.GetBlobClient(blobName);
// Download the blob's contents and save it to a file
Azure.Response responseDTA = await blob.DownloadToAsync(ms);
//set value
ms.Position = 0;
//convert to byte[]
pdfBytes = ms.ToArray();
}
return pdfBytes;
}
UploadPdf:
public static async Task<Azure.Response<Azure.Storage.Blobs.Models.BlobContentInfo>> UpdloadPdf(byte[] pdfBytes, string connectionString, string blobContainerName, string blobName)
{
Azure.Response<Azure.Storage.Blobs.Models.BlobContentInfo> result = null;
using (MemoryStream ms = new MemoryStream(pdfBytes))
{
//this statement may not be necessary
ms.Position = 0;
// Get a reference to the container and then create it
BlobContainerClient container = new BlobContainerClient(connectionString, blobContainerName);
await container.CreateAsync();
// Get a reference to the blob
BlobClient blob = container.GetBlobClient(blobName);
//upload
result = await blob.UploadAsync(ms);
}
return result;
}
Here's a PDF file for testing.
Related
I have generated a pdf file from html and now I need to save it to a folder in my project.
I am able to get the generated pdf to download locally but when I send it to the file folder it gets corrupted and will not open.
public void CreateHTML(ComplaintIntakeData cd)
{
string formHtml = "<table class=\"MsoNormal\">";
string complaintTypeHtml = PCSUtilities.GetComplaintTypeHTML(cd);
string providerHtml = "";
if (cd.Providers != null && cd.Providers.Count > 0)
{
providerHtml = PCSUtilities.GetProviderHTML(cd);
}
string facilityHtml = PCSUtilities.GetFacilityHTML(cd);
string anonymousHtml = PCSUtilities.GetAnonymousHTML(cd);
string contactHtml = PCSUtilities.GetContactHTML(cd);
string patientHtml = PCSUtilities.GetPatientHTML(cd);
string detailsHtml = PCSUtilities.GetComplaintDetailsHTML(cd);
formHtml = formHtml + complaintTypeHtml + providerHtml + facilityHtml + anonymousHtml + contactHtml + patientHtml + detailsHtml + "</table>";
formHtml = formHtml.Replace("''", "\"");
// Load HTML template for letter and replace template fields with provider data
string htmlContent = File.ReadAllText(Server.MapPath("~/ComplaintIntakeForm.html"));
htmlContent = htmlContent.Replace("<%ComplaintInformation%>", formHtml);
string fileName = "ComplaintIntakeFile_" + cd.ComplaintGuid.ToString() +".pdf";
using (MemoryStream memStream = new MemoryStream())
{
try
{
// Load up a new PDF doc.
iTextSharp.text.Document pdfDoc = new iTextSharp.text.Document(PageSize.LETTER);
PdfWriter writer = PdfWriter.GetInstance(pdfDoc, memStream);
// writer.CompressionLevel = PdfStream.NO_COMPRESSION;
// Make document tagged PDFVERSION_1_7
writer.SetPdfVersion(PdfWriter.PDF_VERSION_1_7);
writer.SetTagged();
// Set document metadata
writer.ViewerPreferences = PdfWriter.DisplayDocTitle;
pdfDoc.AddLanguage("en-US");
pdfDoc.AddTitle("Complaint Intake Form");
writer.CreateXmpMetadata();
pdfDoc.Open();
var tagProcessors = (DefaultTagProcessorFactory)Tags.GetHtmlTagProcessorFactory();
//tagProcessors.RemoveProcessor(HTML.Tag.IMG);
//tagProcessors.AddProcessor(HTML.Tag.IMG, new CustomImageTagProcessor());
var cssFiles = new CssFilesImpl();
cssFiles.Add(XMLWorkerHelper.GetInstance().GetDefaultCSS());
var cssResolver = new StyleAttrCSSResolver(cssFiles);
var charset = Encoding.UTF8;
var context = new HtmlPipelineContext(new CssAppliersImpl(new XMLWorkerFontProvider()));
context.SetAcceptUnknown(true).AutoBookmark(true).SetTagFactory(tagProcessors);
var htmlPipeline = new HtmlPipeline(context, new PdfWriterPipeline(pdfDoc, writer));
var cssPipeline = new CssResolverPipeline(cssResolver, htmlPipeline);
var worker = new XMLWorker(cssPipeline, true);
var xmlParser = new XMLParser(true, worker, charset);
try
{
using (var sr = new StringReader(htmlContent))
{
xmlParser.Parse(sr);
// xmlParser.Flush();
}
}
catch (Exception e)
{
Response.Write(e.Message);
}
pdfDoc.Close();
//writer.Close();
///this creates a pdf download.
Response.ContentType = "application/pdf";
Response.AddHeader("content-disposition", "attachment; filename=" + fileName);
Response.OutputStream.Write(memStream.GetBuffer(), 0, memStream.GetBuffer().Length);
}
catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show("The following error occurred:\n" + ex.ToString());
}
}
}
when I add the following to create the file. The file is created but it is corrupted and cannot open as a pdf
using (FileStream file = new FileStream(Server.MapPath("~/tempFiles/") + fileName, FileMode.CreateNew))
{
byte[] bytes = new byte[memStream.Length];
memStream.Read(bytes, 0, memStream.Length);
file.Write(bytes, 0, bytes.Length);
}
I think this answer is relevant:
Copy MemoryStream to FileStream and save the file?
Your two code snippets use both memStream and memString and without seeing all the code in context, I'm guessing. Assuming memStream is a Stream that contains the contents of your PDF, you can write it to a file like this:
using (FileStream file = new FileStream(Server.MapPath("~/tempFiles/") + fileName, FileMode.CreateNew))
{
memStream.Position = 0;
memStream.CopyTo(file);
}
I wound up moving the new FileStream call into the PdfWriter.GetInstance method in place of the memStream variable. And was able to get rid of the using filestream code all together.
PdfWriter writer = PdfWriter.GetInstance(pdfDoc, new FileStream(Server.MapPath(path)+"/" + fileName, FileMode.CreateNew));
This is the old code where copy to a local path, but now i need to save the file on SharePoint. How can i use stream with it and write the stream to file.
File.Copy(oTemplatePath, destinationPath, true);
using (WordprocessingDocument document = WordprocessingDocument.Open(destinationPath, true))
{
document.GetMergeFields("reference_number").ReplaceWithText(refrenceNumber);
document.MainDocumentPart.Document.Save();
for (int i = 0; i < newDoc.jsonFields.Count; i++)
{
if (newDoc.jsonFields[i].type == "date")
{
document.GetMergeFields(newDoc.jsonFields[i].controlName).ReplaceWithText(DateTime.Parse(newDoc.jsonFields[i].data).ToShortDateString());
document.MainDocumentPart.Document.Save();
}
else
{
document.GetMergeFields(newDoc.jsonFields[i].controlName).ReplaceWithText(newDoc.jsonFields[i].data);
document.MainDocumentPart.Document.Save();
}
}
//document.GetMergeFields(newDoc.jsonFields[i].controlName).ReplaceWithText(newDoc.jsonFields[i].data);
//document.MainDocumentPart.Document.Save();
}
You can save to local temp folder
string tempDocx = Path.Combine(Path.GetTempPath(), fileName);
logger.Trace($"Creating Word document {tempDocx}");
File.Delete(tempDocx);
File.Copy("Template.docx", tempDocx);
Then upload to SharePoint, here using a FileStream
using (IO.FileStream fs = new IO.FileStream(tempDocx, IO.FileMode.Open))
{
List documentsList = clientContext.Web.Lists.GetByTitle(libTitle);
clientContext.Load(documentsList.RootFolder);
clientContext.ExecuteQuery();
var fileCreationInformation = new FileCreationInformation();
//Assign to content byte[] i.e. documentStream
fileCreationInformation.ContentStream = fs;
//Allow owerwrite of document
fileCreationInformation.Overwrite = true;
//Upload URL
fileCreationInformation.Url = documentsList.RootFolder.ServerRelativeUrl + "/" + IO.Path.GetFileName(tempDocx);
uploadFile = documentsList.RootFolder.Files.Add(fileCreationInformation);
clientContext.Load(uploadFile);
clientContext.ExecuteQuery();
}
I'm trying to open a PDF with itextsharp that was encrypted with AES 256 and display it. The PDF was encrypted with itextsharp as well. I'm using iTextSharp 5.5.0.0. This code works if the encryption is set to 'standard encryption'.
An exception is thrown on the closing bracket of the inner 'using': Arithmetic operation resulted in an overflow.
string path = Server.MapPath("~/App_Data/pdf/foo.pdf");
string password = "openSesame";
Response.Clear();
Response.ClearHeaders();
Response.AddHeader("Expires", "0");
Response.AddHeader("Cache-Control", "private");
Response.AddHeader("content-disposition", "inline");
Response.ContentType = "application/pdf";
using (MemoryStream memoryStream = new MemoryStream())
{
using (PdfReader reader = new PdfReader(path, Encoding.UTF8.GetBytes(password)))
using (PdfStamper stamper = new PdfStamper(reader, memoryStream))
{
}
Response.BinaryWrite(memoryStream.GetBuffer());
}
Response.End();
Update (forgot encryption code):
using (FileStream fileStream = new FileStream(path, FileMode.Create))
{
PdfCopyFields copy = new PdfCopyFields(fileStream);
var bytes = Encoding.UTF8.GetBytes(password);
copy.SetEncryption(bytes, bytes, 0, PdfWriter.ENCRYPTION_AES_256);
// add some documents with 'copy.AddDocument()';
copy.Close();
}
Am I missing something?
Here's a quick sample I put together that works to encrypt a PDF with 256-bit AES encryption:
var openDialog = new OpenFileDialog();
openDialog.DefaultExt = "pdf";
if (openDialog.ShowDialog() == true)
{
using (var input = openDialog.OpenFile())
{
var saveDialog = new SaveFileDialog();
saveDialog.DefaultExt = "pdf";
if (saveDialog.ShowDialog() == true)
{
using (var reader = new PdfReader(input))
{
using (var output = saveDialog.OpenFile())
{
PdfEncryptor.Encrypt(
reader, output,
PdfWriter.ENCRYPTION_AES_256,
"password", "password",
PdfWriter.ALLOW_PRINTING);
}
}
}
}
}
I looked into iTextSharp and SharpPDF and Report.Net as well as PDFSharp.
None of these open source projects have good documentation OR do not work with VS 2012.
Does anyone have a recommended solution or can show me the documentation?
My employer blocks many sites and although Google is not blocked, some of the results are.
I plan on using C# with WinForms and obtaining my data from an Access DB
Hey #Cocoa Dev get this a complete example with diferent functions.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.IO;
using iTextSharp.text.pdf;
using System.Data;
using System.Text;
using System.util.collections;
using iTextSharp.text;
using System.Net.Mail;
public partial class PDFScenarios : System.Web.UI.Page
{
public string P_InputStream = "~/MyPDFTemplates/ex1.pdf";
public string P_InputStream2 = "~/MyPDFTemplates/ContactInfo.pdf";
public string P_InputStream3 = "~/MyPDFTemplates/MulPages.pdf";
public string P_InputStream4 = "~/MyPDFTemplates/CompanyLetterHead.pdf";
public string P_OutputStream = "~/MyPDFOutputs/ex1_1.pdf";
//Read all 'Form values/keys' from an existing multi-page PDF document
public void ReadPDFformDataPageWise()
{
PdfReader reader = new PdfReader(Server.MapPath(P_InputStream3));
AcroFields form = reader.AcroFields;
try
{
for (int page = 1; page <= reader.NumberOfPages; page++)
{
foreach (KeyValuePair<string, AcroFields.Item> kvp in form.Fields)
{
switch (form.GetFieldType(kvp.Key))
{
case AcroFields.FIELD_TYPE_CHECKBOX:
case AcroFields.FIELD_TYPE_COMBO:
case AcroFields.FIELD_TYPE_LIST:
case AcroFields.FIELD_TYPE_RADIOBUTTON:
case AcroFields.FIELD_TYPE_NONE:
case AcroFields.FIELD_TYPE_PUSHBUTTON:
case AcroFields.FIELD_TYPE_SIGNATURE:
case AcroFields.FIELD_TYPE_TEXT:
int fileType = form.GetFieldType(kvp.Key);
string fieldValue = form.GetField(kvp.Key);
string translatedFileName = form.GetTranslatedFieldName(kvp.Key);
break;
}
}
}
}
catch
{
}
finally
{
reader.Close();
}
}
//Read and alter form values for only second and
//third page of an existing multi page PDF doc.
//Save the changes in a brand new pdf file.
public void ReadAlterPDFformDataInSelectedPages()
{
PdfReader reader = new PdfReader(Server.MapPath(P_InputStream3));
reader.SelectPages("1-2"); //Work with only page# 1 & 2
using (PdfStamper stamper = new PdfStamper(reader, new FileStream(Server.MapPath(P_OutputStream), FileMode.Create)))
{
AcroFields form = stamper.AcroFields;
var fieldKeys = form.Fields.Keys;
foreach (string fieldKey in fieldKeys)
{
//Replace Address Form field with my custom data
if (fieldKey.Contains("Address"))
{
form.SetField(fieldKey, "MyCustomAddress");
}
}
//The below will make sure the fields are not editable in
//the output PDF.
stamper.FormFlattening = true;
}
}
//Extract text from an existing PDF's second page.
private string ExtractText()
{
PdfReader reader = new PdfReader(Server.MapPath(P_InputStream3));
string txt = PdfTextExtractor.GetTextFromPage(reader, 2, new LocationTextExtractionStrategy());
return txt;
}
//Create a brand new PDF from scratch and without a template
private void CreatePDFNoTemplate()
{
Document pdfDoc = new Document();
PdfWriter writer = PdfWriter.GetInstance(pdfDoc, new FileStream(Server.MapPath(P_OutputStream), FileMode.OpenOrCreate));
pdfDoc.Open();
pdfDoc.Add(new Paragraph("Some data"));
PdfContentByte cb = writer.DirectContent;
cb.MoveTo(pdfDoc.PageSize.Width / 2, pdfDoc.PageSize.Height / 2);
cb.LineTo(pdfDoc.PageSize.Width / 2, pdfDoc.PageSize.Height);
cb.Stroke();
pdfDoc.Close();
}
private void fillPDFForm()
{
string formFile = Server.MapPath(P_InputStream);
string newFile = Server.MapPath(P_OutputStream);
PdfReader reader = new PdfReader(formFile);
using (PdfStamper stamper = new PdfStamper(reader, new FileStream(newFile, FileMode.Create)))
{
AcroFields fields = stamper.AcroFields;
// set form fields
fields.SetField("name", "John Doe");
fields.SetField("address", "xxxxx, yyyy");
fields.SetField("postal_code", "12345");
fields.SetField("email", "johndoe#xxx.com");
// flatten form fields and close document
stamper.FormFlattening = true;
stamper.Close();
}
}
//Helper functions
private void SendEmail(MemoryStream ms)
{
MailAddress _From = new MailAddress("XXX#domain.com");
MailAddress _To = new MailAddress("YYY#a.com");
MailMessage email = new MailMessage(_From, _To);
Attachment attach = new Attachment(ms, new System.Net.Mime.ContentType("application/pdf"));
email.Attachments.Add(attach);
SmtpClient mailSender = new SmtpClient("Gmail-Server");
mailSender.Send(email);
}
private void DownloadAsPDF(MemoryStream ms)
{
Response.Clear();
Response.ClearContent();
Response.ClearHeaders();
Response.ContentType = "application/pdf";
Response.AppendHeader("Content-Disposition", "attachment;filename=abc.pdf");
Response.OutputStream.Write(ms.GetBuffer(), 0, ms.GetBuffer().Length);
Response.OutputStream.Flush();
Response.OutputStream.Close();
Response.End();
ms.Close();
}
//Working with Memory Stream and PDF
public void CreatePDFFromMemoryStream()
{
//(1)using PDFWriter
Document doc = new Document();
MemoryStream memoryStream = new MemoryStream();
PdfWriter writer = PdfWriter.GetInstance(doc, memoryStream);
doc.Open();
doc.Add(new Paragraph("Some Text"));
writer.CloseStream = false;
doc.Close();
//Get the pointer to the beginning of the stream.
memoryStream.Position = 0;
//You may use this PDF in memorystream to send as an attachment in an email
//OR download as a PDF
SendEmail(memoryStream);
DownloadAsPDF(memoryStream);
//(2)Another way using PdfStamper
PdfReader reader = new PdfReader(Server.MapPath(P_InputStream2));
using (MemoryStream ms = new MemoryStream())
{
PdfStamper stamper = new PdfStamper(reader, ms);
AcroFields fields = stamper.AcroFields;
fields.SetField("SomeField", "MyValueFromDB");
stamper.FormFlattening = true;
stamper.Close();
SendEmail(ms);
}
}
//Burst-- Make each page of an existing multi-page PDF document
//as another brand new PDF document
private void PDFBurst()
{
string pdfTemplatePath = Server.MapPath(P_InputStream3);
PdfReader reader = new PdfReader(pdfTemplatePath);
//PdfCopy copy;
PdfSmartCopy copy;
for (int i = 1; i < reader.NumberOfPages; i++)
{
Document d1 = new Document();
copy = new PdfSmartCopy(d1, new FileStream(Server.MapPath(P_OutputStream).Replace(".pdf", i.ToString() + ".pdf"), FileMode.Create));
d1.Open();
copy.AddPage(copy.GetImportedPage(reader, i));
d1.Close();
}
}
//Copy a set of form fields from an existing PDF template/doc
//and keep appending to a brand new PDF file.
//The copied set of fields will have different values.
private void AppendSetOfFormFields()
{
PdfCopyFields _copy = new PdfCopyFields(new FileStream(Server.MapPath(P_OutputStream), FileMode.Create));
_copy.AddDocument(new PdfReader(a1("1")));
_copy.AddDocument(new PdfReader(a1("2")));
_copy.AddDocument(new PdfReader(new FileStream(Server.MapPath("~/MyPDFTemplates/Myaspx.pdf"), FileMode.Open)));
_copy.Close();
}
//ConcatenateForms
private byte[] a1(string _ToAppend)
{
using (var existingFileStream = new FileStream(Server.MapPath(P_InputStream), FileMode.Open))
using (MemoryStream stream = new MemoryStream())
{
// Open existing PDF
var pdfReader = new PdfReader(existingFileStream);
var stamper = new PdfStamper(pdfReader, stream);
var form = stamper.AcroFields;
var fieldKeys = form.Fields.Keys;
foreach (string fieldKey in fieldKeys)
{
form.RenameField(fieldKey, fieldKey + _ToAppend);
}
// "Flatten" the form so it wont be editable/usable anymore
stamper.FormFlattening = true;
stamper.Close();
pdfReader.Close();
return stream.ToArray();
}
}
//Working with Image
private void AddAnImage()
{
using (var inputPdfStream = new FileStream(#"C:\MyInput.pdf", FileMode.Open))
using (var inputImageStream = new FileStream(#"C:\img1.jpg", FileMode.Open))
using (var outputPdfStream = new FileStream(#"C:\MyOutput.pdf", FileMode.Create))
{
PdfReader reader = new PdfReader(inputPdfStream);
PdfStamper stamper = new PdfStamper(reader, outputPdfStream);
PdfContentByte pdfContentByte = stamper.GetOverContent(1);
var image = iTextSharp.text.Image.GetInstance(inputImageStream);
image.SetAbsolutePosition(1, 1);
pdfContentByte.AddImage(image);
stamper.Close();
}
}
//Add Company Letter-Head/Stationary to an existing pdf
private void AddCompanyStationary()
{
PdfReader reader = new PdfReader(Server.MapPath(P_InputStream2));
PdfReader s_reader = new PdfReader(Server.MapPath(P_InputStream4));
using (PdfStamper stamper = new PdfStamper(reader, new FileStream(Server.MapPath(P_OutputStream), FileMode.Create)))
{
PdfImportedPage page = stamper.GetImportedPage(s_reader, 1);
int n = reader.NumberOfPages;
PdfContentByte background;
for (int i = 1; i <= n; i++)
{
background = stamper.GetUnderContent(i);
background.AddTemplate(page, 0, 0);
}
stamper.Close();
}
}
Try this example:
using iTextSharp.text;
// Set up the fonts to be used on the pages
private Font _largeFont = new Font(Font.FontFamily.HELVETICA, 18, Font.BOLD, BaseColor.BLACK);
private Font _standardFont = new Font(Font.FontFamily.HELVETICA, 14, Font.NORMAL, BaseColor.BLACK);
private Font _smallFont = new Font(Font.FontFamily.HELVETICA, 10, Font.NORMAL, BaseColor.BLACK);
public void Build()
{
iTextSharp.text.Document doc = null;
try
{
// Initialize the PDF document
doc = new Document();
iTextSharp.text.pdf.PdfWriter writer = iTextSharp.text.pdf.PdfWriter.GetInstance(doc,
new System.IO.FileStream(System.IO.Directory.GetCurrentDirectory() + "\\ScienceReport.pdf",
System.IO.FileMode.Create));
// Set margins and page size for the document
doc.SetMargins(50, 50, 50, 50);
// There are a huge number of possible page sizes, including such sizes as
// EXECUTIVE, LEGAL, LETTER_LANDSCAPE, and NOTE
doc.SetPageSize(new iTextSharp.text.Rectangle(iTextSharp.text.PageSize.LETTER.Width,
iTextSharp.text.PageSize.LETTER.Height));
// Add metadata to the document. This information is visible when viewing the
// document properities within Adobe Reader.
doc.AddTitle("My Science Report");
doc.AddCreator("M. Lichtenberg");
doc.AddKeywords("paper airplanes");
// Add Xmp metadata to the document.
this.CreateXmpMetadata(writer);
// Open the document for writing content
doc.Open();
// Add pages to the document
this.AddPageWithBasicFormatting(doc);
this.AddPageWithInternalLinks(doc);
this.AddPageWithBulletList(doc);
this.AddPageWithExternalLinks(doc);
this.AddPageWithImage(doc, System.IO.Directory.GetCurrentDirectory() + "\\FinalGraph.jpg");
// Add page labels to the document
iTextSharp.text.pdf.PdfPageLabels pdfPageLabels = new iTextSharp.text.pdf.PdfPageLabels();
pdfPageLabels.AddPageLabel(1, iTextSharp.text.pdf.PdfPageLabels.EMPTY, "Basic Formatting");
pdfPageLabels.AddPageLabel(2, iTextSharp.text.pdf.PdfPageLabels.EMPTY, "Internal Links");
pdfPageLabels.AddPageLabel(3, iTextSharp.text.pdf.PdfPageLabels.EMPTY, "Bullet List");
pdfPageLabels.AddPageLabel(4, iTextSharp.text.pdf.PdfPageLabels.EMPTY, "External Links");
pdfPageLabels.AddPageLabel(5, iTextSharp.text.pdf.PdfPageLabels.EMPTY, "Image");
writer.PageLabels = pdfPageLabels;
}
catch (iTextSharp.text.DocumentException dex)
{
// Handle iTextSharp errors
}
finally
{
// Clean up
doc.Close();
doc = null;
}
}
You can always just create an html page and then convert that to pdf using wkhtmltopdf. This has the benefit of you not having to construct the pdf with a library such as iText. You just make a text file (html) and then pass it to the wkhtmltopdf executable.
See Calling wkhtmltopdf to generate PDF from HTML for more info.
I'm generating a PDF document based on template. The document has multiple pages. The document can have about 5000 pages. When creating the 500-th page I get an overflow RAM (memory). Any idea?
public static void CreateBankBlank2012Year(string pdfTemplatePath, string directoryOutPdf, string nameOutPdf, AnnualReportsFilterParameters filterParametrs, string serverPath)
{
// Get details salary
IEnumerable<SalayDetailsForPdf> dataSalaryDetails = (IEnumerable<SalayDetailsForPdf>) GetSalaryData(filterParametrs);
String fontPath = Path.Combine(serverPath + "\\Fonts", "STSONG.ttf");
Font font = FontFactory.GetFont(fontPath, BaseFont.IDENTITY_H, 8);
using (Document document = new Document())
{
using (PdfSmartCopy copy = new PdfSmartCopy(
document, new FileStream(directoryOutPdf + nameOutPdf, FileMode.Create))
)
{
document.Open();
foreach (var data in dataSalaryDetails)
{
PdfReader reader = new PdfReader(pdfTemplatePath + #"\EmptyTemplateBankBlank_2012.pdf");
using (var ms = new MemoryStream())
{
using (PdfStamper stamper = new PdfStamper(reader, ms))
{
stamper.AcroFields.AddSubstitutionFont(font.BaseFont);
AcroFields form = stamper.AcroFields;
form.SetField("t1_address1", data.Address1);
form.SetField("t1_name", data.NameHieroglyphic);
// Other field ...
stamper.FormFlattening = true;
}
reader = new PdfReader(ms.ToArray());
copy.AddPage(copy.GetImportedPage(reader, 1));
}
}
}
}
}
p.s
I'm trying resolve my problem as follow:
generating empty pages based on template
private static void GeneratePdfFromTemplate(string directoryOutPdf, string nameOutPdf, string pdfTemplatePath, int countPages)
{
using (Document document = new Document())
{
using (PdfSmartCopy copy = new PdfSmartCopy(
document, new FileStream(directoryOutPdf + nameOutPdf, FileMode.Create))
)
{
document.Open();
PdfReader reader = new PdfReader(pdfTemplatePath + #"\EmptyTemplateBankBlank_2012.pdf");
for (int i = 0; i < countPages; i++)
{
copy.AddPage(copy.GetImportedPage(reader, 1));
}
reader.Close();
copy.Close();
}
document.Close();
}
GC.Collect();
}
But after a generating I can't set values to the fields.
I'm found solution for my problem, if anyone else would be interested :
private static void SettingFieltValue(Font font, IEnumerable<SalayDetailsForPdf> dataSalaryDetails, int selectedYear, string directoryOutPdf, string nameOutPdf, string pdfTemplatePath)
{
string pdfTemplate = pdfTemplatePath + #"\EmptyTemplateBankBlank_2012.pdf";
string newFile = directoryOutPdf + nameOutPdf;
var fs = new FileStream(newFile, FileMode.Create);
var conc = new PdfConcatenate(fs, true);
foreach (var data in dataSalaryDetails)
{
var reader = new PdfReader(pdfTemplate);
using (var ms = new MemoryStream())
{
using (PdfStamper stamper = new PdfStamper(reader, ms))
{
stamper.AcroFields.AddSubstitutionFont(font.BaseFont);
AcroFields form = stamper.AcroFields;
form.SetField("t1_name", data.NameHieroglyphic);
//Other field
stamper.FormFlattening = true;
stamper.Close();
}
reader = new PdfReader(ms.ToArray());
ms.Close();
}
conc.AddPages(reader);
reader.Close();
}
conc.Close();
}