how to insert table for existing form fill pdf using itextsharp - itext

I have a form fill pdf where we dynamically add text field values to pdf. after adding this i need to add the table in the same page of the pdf.
if i add table it creates new pdf with only table. all other existing data are cleared.
I am using below code :
private void AddTableToPDF()
{
Document doc = new Document(iTextSharp.text.PageSize.LETTER, 10, 10, 100, 100);
try
{
string pdfFilePath = #"D:\Temp\PDF\Inspection Form - Steel Girder.pdf";
PdfWriter wri = PdfWriter.GetInstance(doc, new FileStream(pdfFilePath, FileMode.Append));
doc.Open();//Open Document to write
System.IO.MemoryStream mStream = new System.IO.MemoryStream();
PdfWriter writer = PdfWriter.GetInstance(doc, mStream);
DataTable dt = GetDataTable();
DataTable dtHeader = new DataTable();
dtHeader = GetHeaderDataTable();
if (dtHeader != null)
{
PdfPTable PdfTable = new PdfPTable(dtHeader.Columns.Count);
PdfPCell PdfPCell = null;
for (int rows = 0; rows < dtHeader.Rows.Count; rows++)
{
for (int column = 0; column < dtHeader.Columns.Count; column++)
{
PdfPCell = new PdfPCell(new Phrase(new Chunk(dtHeader.Rows[rows][column].ToString(), font8)));
PdfTable.AddCell(PdfPCell);
}
}
doc.Add(PdfTable); // add pdf table to the document
}
if (dt != null)
{
PdfPTable PdfTable = new PdfPTable(dt.Columns.Count);
PdfPCell PdfPCell = null;
PdfPCell = new PdfPCell(new Phrase(new Chunk("Reference", font8)));
PdfTable.AddCell(PdfPCell);
PdfPCell = new PdfPCell(new Phrase(new Chunk("Remark", font8)));
PdfTable.AddCell(PdfPCell);
PdfPCell = new PdfPCell(new Phrase(new Chunk("Description", font8)));
PdfTable.AddCell(PdfPCell);
for (int rows = 0; rows < dt.Rows.Count; rows++)
{
for (int column = 0; column < dt.Columns.Count; column++)
{
PdfPCell = new PdfPCell(new Phrase(new Chunk(dt.Rows[rows][column].ToString(), font8)));
PdfTable.AddCell(PdfPCell);
}
}
doc.Add(PdfTable); // add pdf table to the document
}
}
catch (DocumentException docEx)
{
Response.Write(docEx.Message);
}
catch (IOException ioEx)
{
Response.Write(ioEx.Message);
}
catch (Exception ex)
{
Response.Write(ex.Message);
}
finally
{
doc.Close();
}
}

Suppose your main PDF is named with m1.pdf. you just create a new PDF with name m2.pdf which will contain the new Table that you need to add. now just merge these Two PDF (m1.pdf & m2.pdf) in to new one 'MergedNerw.pdf')
To Merge Two PDF please use following code this Works fine i have Tested it:
protected void BtnMerge_Click(object sender, EventArgs e)
{
String[] files = #"d:\m1.pdf,d:\m2.pdf".Split(',');
MergeFiles(#"d:\MergedNew.pdf", files);
}
public void MergeFiles(string destinationFile, string[] sourceFiles)
{
if (System.IO.File.Exists(destinationFile))
System.IO.File.Delete(destinationFile);
string[] sSrcFile;
sSrcFile = new string[2];
string[] arr = new string[2];
for (int i = 0; i <= sourceFiles.Length - 1; i++)
{
if (sourceFiles[i] != null)
{
if (sourceFiles[i].Trim() != "")
arr[i] = sourceFiles[i].ToString();
}
}
if (arr != null)
{
sSrcFile = new string[2];
for (int ic = 0; ic <= arr.Length - 1; ic++)
{
sSrcFile[ic] = arr[ic].ToString();
}
}
try
{
int f = 0;
PdfReader reader = new PdfReader(sSrcFile[f]);
int n = reader.NumberOfPages;
//Response.Write("There are " + n + " pages in the original file.");
Document document = new Document(PageSize.A4);
PdfWriter writer = PdfWriter.GetInstance(document, new FileStream(destinationFile, FileMode.Create));
document.Open();
PdfContentByte cb = writer.DirectContent;
PdfImportedPage page;
int rotation;
while (f < sSrcFile.Length)
{
int i = 0;
while (i < n)
{
i++;
document.SetPageSize(PageSize.A4);
document.NewPage();
page = writer.GetImportedPage(reader, i);
rotation = reader.GetPageRotation(i);
if (rotation == 90 || rotation == 270)
{
cb.AddTemplate(page, 0, -1f, 1f, 0, 0, reader.GetPageSizeWithRotation(i).Height);
}
else
{
cb.AddTemplate(page, 1f, 0, 0, 1f, 0, 0);
}
//Response.Write("\n Processed page " + i);
}
f++;
if (f < sSrcFile.Length)
{
reader = new iTextSharp.text.pdf.PdfReader(sSrcFile[f]);
//get the numnber of pages
n = reader.NumberOfPages;
//Response.Write("There are " + n + " pages in the original file.");
}
}
//Response.Write("Success");
document.Close();
}
catch (Exception e)
{
//Response.Write(e.Message);
}
}
Hope this helps you!

Related

Migrating add image to pdf from iText to PDFBox

In our project we are using iText 5.x version to manipulate PDF files and working to migrate that implementation with PDFBox 2.x version.
There is one add image to pdf page scenario and I have converted that code into PDFBox as good as I could do. :) In existing implementation(iText) they add image in template using PdfTemplate and added that template in annotation using PdfAnnotation class.
I don't know how to do that using PDFBox. Also please check that I migrated existing implementation properly or not as I'm newbie in PDF library using Java.
Add Image to PDF(Using iText):
Document document = null;
PdfReader pdfReader = null;
pdfReader = new PdfReader(SourceFilePath());
//we retrieve the total number of pages and the page size
int total = pdfReader.getNumberOfPages();
Rectangle rectangle = pdfReader.getPageSizeWithRotation(1);
document = new Document(rectangle);
PdfImportedPage page;
PdfCopy.PageStamp stamp;
// step 2: we create a PdfCopy object that listens to the document.
PdfCopy copy = new PdfCopy(document, new FileOutputStream(DestinationFilePath(false));
document.open();
// step 4: adding the content
for (int i = 1; i <= total; i++) {
page = copy.getImportedPage(pdfReader, i);
if(i == 1 || aBarcodeVO.getDisplacementVO().isApplyForAllPages()){
BufferedImage bufferedImage = getImage();
Image img = Image.getInstance(bufferedImage, null);
img.scaleToFit(qrImageSize, qrImageSize);
PdfName imgKey = new PdfName(aBarcodeVO.getImgUniqueId() + i);
Rectangle rectPage = pdfReader.getPageSizeWithRotation(i);
stamp = copy.createPageStamp(page);
PdfImage stream = new PdfImage(img, "", null);
stream.put(imgKey, imgKey);
PdfIndirectObject ref = copy.addToBody(stream);
int rotation = pdfReader.getPageRotation(i);
Rectangle cropBoxRect = pdfReader.getCropBox(i);;
//Explicitly Apply rotation to crop box rectangle.
for (int j = 0; j < (rotation/90); j++) {
cropBoxRect = cropBoxRect.rotate();
}
//added Image in template and template in Annotation and finally annotation is added in PDF through PdfCopy.PageStamp
PdfTemplate template = PdfTemplate.createTemplate(copy, img.getPlainWidth(), img.getPlainHeight());
img.setAbsolutePosition(0, 0);
img.setRotationDegrees(rotation);
img.setDirectReference(ref.getIndirectReference());
template.addImage(img);
Rectangle rect = new Rectangle(rectLlx, rectLly, rectUrx, rectUry);
rect.setBorderWidth(0.5f);
rect.setBorderColor(new BaseColor(0xFF, 0x00, 0x00));
PdfAnnotation annotation = PdfAnnotation.createStamp(copy, rect, null, "AnnotationOnly");
annotation.setAppearance(PdfAnnotation.APPEARANCE_NORMAL, template);
annotation.setFlags(PdfAnnotation.FLAGS_PRINT + PdfAnnotation.FLAGS_LOCKED);
annotation.setRotate(rotation);
PdfName annotKey = getAnnotKey(i);
annotation.put(annotKey, annotKey);
stamp.addAnnotation(annotation);
stamp.alterContents();
}
copy.addPage(page);
}
copy.freeReader(pdfReader);
try {
if (document != null) {
document.close();
}
} catch (Exception e) {
System.out.println("Exception in handleAddBarCode() while closing():document:" + e);
}
try {
if (pdfReader != null) {
pdfReader.close();
}
} catch (Exception e) {
System.out.println("Exception in handleAddBarCode() while closing():pdfReader:" + e);
}
Add Image to PDF(Using PDFBox):
PDDocument pdDocument = PDDocument.load(new File(SourceFilePath()));
int total = pdDocument.getNumberOfPages();
PDPage page = pdDocument.getDocumentCatalog().getPages().get(0);
PDRectangle rectangle = getRotatedMediaBox(page);
PDPage pdPage = new PDPage(rectangle);
PDDocument newDocument = new PDDocument();
for (int i = 0; i < total; i++) {
pdPage = newDocument.importPage(pdDocument.getPage(i));
PDRectangle pageRect = getRotatedMediaBox(pdPage);
int rotation = pdPage.getRotation();
PDRectangle cropBoxRect = page.getCropBox();
//Calculate margin between crop box rectangle and page rectangle.
float[] margins = getCropBoxMargin(pageRect, cropBoxRect, rotation);
if (rotation == 90 || rotation == 270) {
cropBoxRect = new PDRectangle(cropBoxRect.getLowerLeftY(), cropBoxRect.getLowerLeftX(), cropBoxRect.getHeight(),
cropBoxRect.getWidth());
}
BufferedImage bufferedImage = getImage();
PDPageContentStream pageContentStream = new PDPageContentStream(newDocument, pdPage,
PDPageContentStream.AppendMode.APPEND, true);
PDImageXObject image = JPEGFactory.createFromImage(newDocument, bufferedImage);
if (rotation == 90 || rotation == 270) {
Matrix matrix = Matrix.getRotateInstance(Math.toRadians(rotation), 0, 0);
PDRectangle cropBox = pdPage.getCropBox();
float tx = (cropBox.getLowerLeftX() + cropBox.getUpperRightX()) / 2;
float ty = (cropBox.getLowerLeftY() + cropBox.getUpperRightY()) / 2;
Rectangle rectang = cropBox.transform(matrix).getBounds();
float scale = Math.min(cropBox.getWidth() / (float)rectang.getWidth(), cropBox.getHeight() / (float)rectang.getHeight());
pageContentStream.transform(Matrix.getTranslateInstance(tx, ty));
pageContentStream.transform(matrix);
pageContentStream.transform(Matrix.getScaleInstance(scale, scale));
pageContentStream.transform(Matrix.getTranslateInstance(-tx, -ty));
}
pageContentStream.drawImage(image, rectLlx, rectLly, qrImageSize, qrImageSize);
pageContentStream.close();
}
newDocument.save(new File(DestinationFilePath(false)));
newDocument.close();
pdDocument.close();
Please help me on this or at least looking forward for your suggestions for code needs to rectify of PDFBox implementation.

Hundred thousands of datatable records to PDF in web API

I'm trying to create PDF from the DataTable in web api using ADO.Net. Unfortunately based on filters some times I may get very less records & able to download without any problem. Sometimes may be very huge like 200 thousand of records. When I'm checking in local my system its getting hang while converting the dt to PDF. My code is like below:
private FileContentResult ExportPDF(DataTable dataTable)
{
string Name = "Logs";
System.IO.MemoryStream mStream = new System.IO.MemoryStream();
byte[] content = null;
try
{
string[] columnNames = (from dc in dataTable.Columns.Cast<DataColumn>() select dc.ColumnName).ToArray();
int count = columnNames.Length;
object[] array = new object[count];
dataTable.Rows.Add(array);
Document pdfDoc = new Document(PageSize.A2, 10f, 10f, 10f, 0f);
PdfWriter writer = PdfWriter.GetInstance(pdfDoc, mStream);
int cols = dataTable.Columns.Count;
int rows = dataTable.Rows.Count;
HeaderFooter header = new HeaderFooter(new Phrase(Name), false);
// Remove the border that is set by default
header.Border = iTextSharp.text.Rectangle.TITLE;
// Align the text: 0 is left, 1 center and 2 right.
header.Alignment = Element.ALIGN_CENTER;
pdfDoc.Header = header;
// Header.
pdfDoc.Open();
iTextSharp.text.Table pdfTable = new iTextSharp.text.Table(cols, rows);
pdfTable.BorderWidth = 1; pdfTable.Width = 100;
pdfTable.Padding = 1; pdfTable.Spacing = 4;
//creating table headers
for (int i = 0; i < cols; i++)
{
Cell cellCols = new Cell();
Chunk chunkCols = new Chunk();
iTextSharp.text.Font ColFont = FontFactory.GetFont(FontFactory.HELVETICA, 14, iTextSharp.text.Font.BOLD, iTextSharp.text.BaseColor.Black);
chunkCols = new Chunk(dataTable.Columns[i].ColumnName, ColFont);
cellCols.Add(chunkCols);
pdfTable.AddCell(cellCols);
}
//creating table data (actual result)
for (int k = 0; k < rows; k++)
{
for (int j = 0; j < cols; j++)
{
Cell cellRows = new Cell();
iTextSharp.text.Font RowFont = FontFactory.GetFont(FontFactory.HELVETICA, 12);
Chunk chunkRows = new Chunk(dataTable.Rows[k][j].ToString(), RowFont);
cellRows.Add(chunkRows);
pdfTable.AddCell(cellRows);
}
}
pdfDoc.Add(pdfTable);
pdfDoc.Close();
content = mStream.ToArray();
return File(content, "application/pdf", "LogReports.pdf");
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}

Read roman page number of page

in Adobe Reader the first pages of a ebook can have roman format page number as shown in attached image below
Image : http://i.stack.imgur.com/GSm0Q.jpg
I would like to read these page numbers out (not the indexed page number) with iText but I don't know which properties (labels or annotations..) I should use. I could already open file with PdfReader, loop through all pages but have no idea what I should access for these roman numbers
using (Stream pdfStream = new FileStream(sourceFileName, FileMode.Open))
{
PdfReader pdfReader = new PdfReader(pdfStream);
for (int index = 1; index <= pdfReader.NumberOfPages; index++)
{
}
}
Thanks.
You are looking for the PageLabelExample. In this example, we have a PDF, page_labels.pdf that has pages numbered like this:
In the listPageLabels() method, we create a txt file with all the page labels:
public void listPageLabels(String src, String dest) throws IOException {
// no PDF, just a text file
PrintStream out = new PrintStream(new FileOutputStream(dest));
PdfReader reader = new PdfReader(src);
String[] labels = PdfPageLabels.getPageLabels(reader);
for (int i = 0; i < labels.length; i++) {
out.println(labels[i]);
}
out.flush();
out.close();
reader.close();
}
The result looks like this:
A
B
1
2
3
Movies-4
Movies-5
Movies-6
Movies-7
Movies-8
If you want an iTextSharp example, take a look at this method:
/**
* Reads the page labels from an existing PDF
* #param src the existing PDF
*/
public string ListPageLabels(byte[] src) {
StringBuilder sb = new StringBuilder();
String[] labels = PdfPageLabels.GetPageLabels(new PdfReader(src));
for (int i = 0; i < labels.Length; i++) {
sb.Append(labels[i]);
sb.AppendLine();
}
return sb.ToString();
}
Update
As promised in the comment section: PdfPageLabels.cs
I am not a C# developer, but this is a quick and dirty version of the GetPageLabels() method that doesn't add a prefix:
public static String[] GetPageLabels(PdfReader reader) {
int n = reader.NumberOfPages;
PdfDictionary dict = reader.Catalog;
PdfDictionary labels = (PdfDictionary)PdfReader.GetPdfObjectRelease(dict.Get(PdfName.PAGELABELS));
if (labels == null)
return null;
String[] labelstrings = new String[n];
Dictionary<int, PdfObject> numberTree = PdfNumberTree.ReadTree(labels);
int pagecount = 1;
char type = 'D';
for (int i = 0; i < n; i++) {
if (numberTree.ContainsKey(i)) {
PdfDictionary d = (PdfDictionary)PdfReader.GetPdfObjectRelease(numberTree[i]);
if (d.Contains(PdfName.ST)) {
pagecount = ((PdfNumber)d.Get(PdfName.ST)).IntValue;
}
else {
pagecount = 1;
}
if (d.Contains(PdfName.S)) {
type = ((PdfName)d.Get(PdfName.S)).ToString()[1];
}
else {
type = 'e';
}
}
switch (type) {
default:
labelstrings[i] = "" + pagecount;
break;
case 'R':
labelstrings[i] = RomanNumberFactory.GetUpperCaseString(pagecount);
break;
case 'r':
labelstrings[i] = RomanNumberFactory.GetLowerCaseString(pagecount);
break;
case 'A':
labelstrings[i] = RomanAlphabetFactory.GetUpperCaseString(pagecount);
break;
case 'a':
labelstrings[i] = RomanAlphabetFactory.GetLowerCaseString(pagecount);
break;
case 'e':
labelstrings[i] = "";
break;
}
pagecount++;
}
return labelstrings;
}

Extracted images from PDF using iTextsharp not in correct format - C#

I am using iTextsharp to extract images from the PDF file, i am able to extract images but the extracted images are not in correct format (i.e. it looks like negative proof).
Code:
string sFilePath = "Test3.pdf";
int pageNum = 1;
PdfReader pdf = new PdfReader(sFilePath);
PdfDictionary pg = pdf.GetPageN(pageNum);
PdfDictionary res = (PdfDictionary)PdfReader.GetPdfObject(pg.Get(PdfName.RESOURCES));
PdfDictionary xobj = (PdfDictionary)PdfReader.GetPdfObject(res.Get(PdfName.XOBJECT));
if (xobj == null) { return; }
int imageCount = 0;
foreach (PdfName name in xobj.Keys)
{
PdfObject obj = xobj.Get(name);
if (!obj.IsIndirect()) { continue; }
PdfDictionary tg = (PdfDictionary)PdfReader.GetPdfObject(obj);
PdfName type = (PdfName)PdfReader.GetPdfObject(tg.Get(PdfName.SUBTYPE));
if (!type.Equals(PdfName.IMAGE)) { continue; }
int XrefIndex = Convert.ToInt32(((PRIndirectReference)obj).Number.ToString(System.Globalization.CultureInfo.InvariantCulture));
PdfObject pdfObj = pdf.GetPdfObject(XrefIndex);
PdfStream pdfStrem = (PdfStream)pdfObj;
byte[] bytes = PdfReader.GetStreamBytesRaw((PRStream)pdfStrem);
if (bytes == null) { continue; }
using (System.IO.MemoryStream memStream = new System.IO.MemoryStream(bytes))
{
try
{
memStream.Position = 0;
System.Drawing.Image img = System.Drawing.Image.FromStream(memStream);
if (!Directory.Exists(imgPath))
Directory.CreateDirectory(imgPath);
string path = Path.Combine(imgPath, String.Format(#"{0}.jpg", ++imageCount));
System.Drawing.Imaging.EncoderParameters parms = new System.Drawing.Imaging.EncoderParameters(1);
parms.Param[0] = new System.Drawing.Imaging.EncoderParameter(System.Drawing.Imaging.Encoder.Compression, 0);
var jpegEncoder = ImageCodecInfo.GetImageEncoders().ToList().Find(x => x.FormatID == ImageFormat.Jpeg.Guid);
img.Save(path, jpegEncoder, parms);
}
catch (Exception ex)
{
}
}
}

Align itextsharp table

Does anyone know how to left align a iTextSharp table?
You can use the PdfPTable's HorizontalAlignment property.
Here's a C# test method you can use to experiment:
private void TestTableCreation() {
using (FileStream fs = new FileStream("TableTest.pdf", FileMode.Create)) {
Document doc = new Document(PageSize.A4);
PdfWriter.GetInstance(doc, fs);
doc.Open();
PdfPTable table = new PdfPTable(4);
table.WidthPercentage = 50.0f;
// Options: Element.ALIGN_LEFT (or 0), Element.ALIGN_CENTER (1), Element.ALIGN_RIGHT (2).
table.HorizontalAlignment = Element.ALIGN_LEFT;
for (int i = 1; i <= 20; i++) {
PdfPCell cell = new PdfPCell(new Phrase(String.Format("Cell # {0}", i)));
cell.FixedHeight = 30.0f;
cell.HorizontalAlignment = Element.ALIGN_LEFT;
cell.VerticalAlignment = Element.ALIGN_MIDDLE;
table.AddCell(cell);
}
doc.Add(table);
doc.Close();
}
}
table.HorizontalAlignment = 1;
1:center
0:left
2:right
There are two ways of doing it:
cell.HorizontalAlignment = Element.ALIGN_LEFT;
cell.HorizontalAlignment = 0;