I am creating a PdfTable from iTextSharp but the pdf containing this table does not allow editing in its cells.
How can I make sure that the cell contents are editable in resulting pdf?
iTextSharp.text.pdf.PdfPTable table = new iTextSharp.text.pdf.PdfPTable(columnsToAdd);
table.HorizontalAlignment = 0; //0=Left, 1=Centre, 2=Right
Font headerFont = new Font(Font.HELVETICA, 8f, Font.BOLD, Color.BLACK);
Font bodyFont = new Font(Font.HELVETICA, 6f, Font.NORMAL, Color.BLACK);
PdfPCell cEmpId = new PdfPCell(new Phrase("Emp ID", headerFont));
PdfPCell cEmpAge = new PdfPCell(new Phrase("Emp Age", headerFont));
table.AddCell(cEmpId);
table.AddCell(cEmpAge);
foreach(Child child in childData)
{
PdfPCell cellEmpID = new PdfPCell {FixedHeight = 10f};
cellEmpID.Phrase = (new Phrase(child.Emp_ID.ToString(CultureInfo.InvariantCulture),
bodyFont));
PdfPCell cellEmpAge = new PdfPCell {Phrase = (new Phrase(child.Emp_Age, bodyFont))};
table.AddCell(cellEmpID);
table.AddCell(cellEmpAge);
}
EDIT 1:
Based on Chris's answer, I am going to try out the following code, but not sure at this time.
//WITHIN THE LOOP IN MY CODE ABOVE ADD THESE LINES FOR EVERY PDF CELL
//Create our textfield, the rectangle that we're passing in is ignored and doesn't matter
var tfEmpID = new TextField(writer, new iTextSharp.text.Rectangle(0, 0), child.Emp_ID);
//Set the cell event to our custom IPdfPCellEvent implementation
cellEmpID.CellEvent = new ChildFieldEvent(root, tfEmpID.GetTextField(), 1);
//THEN OUTSIDE THE LOOP
//IMPORTANT! Add the root annotation to the writer which also adds all of the child annotations
writer.AddAnnotation(root);
Related
Here is visual what my problem looks like.
Here is my code that produce that result.
public void intervencionHeaderLogo(string pictureURL,int width, int height)
{
iTextSharp.text.Image image = iTextSharp.text.Image.GetInstance(System.Web.HttpContext.Current.Server.MapPath(pictureURL));
image.ScaleAbsolute(width, height);
image.Alignment = 2;
//Table
PdfPTable table = new PdfPTable(1);
PdfPCell cell = new PdfPCell();
BaseFont bf = BaseFont.CreateFont(BaseFont.TIMES_ROMAN, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
iTextSharp.text.Font font = new iTextSharp.text.Font(bf, 20, iTextSharp.text.Font.NORMAL);
Paragraph p = new Paragraph("Reporte de intervención", font);
//Cell no 1
cell = new PdfPCell();
cell.Border = 0;
cell.AddElement(p);
cell.HorizontalAlignment = Element.ALIGN_CENTER;
table.AddCell(cell);
//Cell no 2
cell = new PdfPCell();
cell.Border = 0;
cell.AddElement(image);
table.AddCell(cell);
//Add table to document
pdfDoc.Add(table);
}
Here is what I want to have.
Any help would be appriciated
I was able to fix it i made a mistake i create a table of 1 when i should have made it of size 2.
//Table
PdfPTable table = new PdfPTable(2);
and the i added a line break like this in the paragraph like this
Paragraph p = new Paragraph("\nReporte de intervención", font);
I'm trying to put a link to another page in my pdf using iTextSharp.
link in rotated cell is not working. other cells work as expected:
FileStream fs = new FileStream("TestPDF.pdf", FileMode.Create, FileAccess.Write, FileShare.None);
Document doc = new Document();
PdfWriter writer = PdfWriter.GetInstance(doc, fs);
doc.Open();
PdfPTable linkTable = new PdfPTable(2);
PdfPCell linkCell = new PdfPCell();
linkCell.HorizontalAlignment = Element.ALIGN_CENTER;
linkCell.Rotation = 90;
linkCell.FixedHeight = 70;
Anchor linkAnchor = new Anchor("Click here");
linkAnchor.Reference = "#target";
Paragraph linkPara = new Paragraph();
linkPara.Add(linkAnchor);
linkCell.AddElement(linkPara);
linkTable.AddCell(linkCell);
PdfPCell linkCell2 = new PdfPCell();
Anchor linkAnchor2 = new Anchor("Click here 2");
linkAnchor2.Reference = "#target";
Paragraph linkPara2 = new Paragraph();
linkPara2.Add(linkAnchor2);
linkCell2.AddElement(linkPara2);
linkTable.AddCell(linkCell2);
linkTable.AddCell(new PdfPCell(new Phrase("cell 3")));
linkTable.AddCell(new PdfPCell(new Phrase("cell 4")));
doc.Add(linkTable);
doc.NewPage();
Anchor destAnchor = new Anchor("top");
destAnchor.Name = "target";
PdfPTable destTable = new PdfPTable(1);
PdfPCell destCell = new PdfPCell();
Paragraph destPara = new Paragraph();
destPara.Add(destAnchor);
destCell.AddElement(destPara);
destTable.AddCell(destCell);
destTable.AddCell(new PdfPCell(new Phrase("cell 2")));
destTable.AddCell(new PdfPCell(new Phrase("cell 3")));
destTable.AddCell(new PdfPCell(new Phrase("cell 4")));
doc.Add(destTable);
doc.Close();
I'm using 'iTextSharp 5.5.8'. I've tried with Chunk.SetAction PdfAction.GotoLocalPage and Chunk.SetLocalGoto. Nothing works for me
Thank you.
Actually iText(Sharp) did create a Link annotation for the anchor in the rotated cell, too, but its coordinates are completely wrong:
/Rect[-0.003 0 53.34 12]
These coordinates even are partially off-page which might explain peculiar behavior of some PDF viewers.
The cause
(I analyzed the iText Java code which has the same issues, because I'm more at home with Java. The matching iTextSharp C# code is very similar, though.)
The cause for this is that the PdfDocument code processing a PdfChunk assumes that the current coordinate system is the original user space coordinate system initialized with the MediaBox data. Thus, it uses the current coordinates without any transformation to generate local Link annotations:
float xMarker = text.getXTLM();
float baseXMarker = xMarker;
float yMarker = text.getYTLM();
...
if (chunk.isAttribute(Chunk.LOCALGOTO)) {
float subtract = lastBaseFactor;
if (nextChunk != null && nextChunk.isAttribute(Chunk.LOCALGOTO))
subtract = 0;
if (nextChunk == null)
subtract += hangingCorrection;
localGoto((String)chunk.getAttribute(Chunk.LOCALGOTO), xMarker, yMarker, xMarker + width - subtract, yMarker + fontSize);
}
(PdfDocument.writeLineToContent(PdfLine, PdfContentByte, PdfContentByte, Object[], float))
Unfortunately, though, cell rotation is implemented by means of a user coordinate system change, e.g. a rotation by 90°:
ct.setSimpleColumn(-0.003f, -0.001f, netWidth + 0.003f, calcHeight);
...
pivotY = cell.getTop() + yPos - currentMaxHeight + cell.getEffectivePaddingBottom();
switch (cell.getVerticalAlignment()) {
case Element.ALIGN_BOTTOM:
pivotX = cell.getLeft() + xPos + cell.getWidth() - cell.getEffectivePaddingRight();
break;
case Element.ALIGN_MIDDLE:
pivotX = cell.getLeft() + xPos + (cell.getWidth() + cell.getEffectivePaddingLeft() - cell.getEffectivePaddingRight() + calcHeight) / 2;
break;
default: //top
pivotX = cell.getLeft() + xPos + cell.getEffectivePaddingLeft() + calcHeight;
break;
}
saveAndRotateCanvases(canvases, 0, 1, -1, 0, pivotX, pivotY);
(PdfPRow.writeCells(int, int, float, float, PdfContentByte[], boolean))
Thus, the PdfDocument code above called for a rotated anchor chunk will position at a generally completely wrong position.
By the way, this does not only concern local Link annotations but all kinds of annotations generated for a chunk. A particularly evil case is that of a generic tag: if a page event listener reacts to a GenericTag event, it can use the coordinates for some drawing action during the call but not as coordinates relative to the MediaBox.
A fix for this most likely requires signaling any coordinate system changes to the PdfDocument and updating the code there to take this information into account when using coordinates for purposes not influenced by those transformations. In particular the GenericTag event should be extended to receive both the transformed and the original coordinates.
I would propose leaving this fix to iText development.
It would have been useful to include the code that is not working for you, so people can focus on the specific issue(s).
I have verified creating local links in general, when both link and destination are in a table (i.e. PdfPCell). This code works as expected:
PdfPTable linkTable = new PdfPTable(2);
PdfPCell linkCell = new PdfPCell();
Anchor linkAnchor = new Anchor("Click here to go to top of next page.");
linkAnchor.Reference = "#target";
Paragraph linkPara = new Paragraph();
linkPara.Add(linkAnchor);
linkCell.AddElement(linkPara);
linkTable.AddCell(linkCell);
linkTable.AddCell(new PdfPCell(new Phrase("cell 2")));
linkTable.AddCell(new PdfPCell(new Phrase("cell 3")));
linkTable.AddCell(new PdfPCell(new Phrase("cell 4")));
doc.Add(linkTable);
doc.NewPage();
Anchor destAnchor = new Anchor("top");
destAnchor.Name = "target";
PdfPTable destTable = new PdfPTable(1);
PdfPCell destCell = new PdfPCell();
Paragraph destPara = new Paragraph();
destPara.Add(destAnchor);
destCell.AddElement(destPara);
destTable.AddCell(destCell);
destTable.AddCell(new PdfPCell(new Phrase("cell 2")));
destTable.AddCell(new PdfPCell(new Phrase("cell 3")));
destTable.AddCell(new PdfPCell(new Phrase("cell 4")));
doc.Add(destTable);
How can i hide the table border using iTextSharp. I am using following code to generate a file:
var document = new Document(PageSize.A4, 50, 50, 25, 25);
// Create a new PdfWriter object, specifying the output stream
var output = new MemoryStream();
var writer = PdfWriter.GetInstance(document, output);
document.Open();
PdfPTable table = new PdfPTable(3);
var bodyFont = FontFactory.GetFont("Arial", 10, Font.NORMAL);
PdfPCell cell = new PdfPCell(new Phrase("Header spanning 3 columns"));
cell.Colspan = 3;
cell.HorizontalAlignment = 1; //0=Left, 1=Centre, 2=Right
table.AddCell(cell);
Font arial = FontFactory.GetFont("Arial", 6, BaseColor.BLUE);
cell = new PdfPCell(new Phrase("Font test is here ", arial));
cell.PaddingLeft = 5f;
cell.Colspan = 1;
table.AddCell(cell);
cell = new PdfPCell(new Phrase("XYX"));
cell.Colspan = 2;
table.AddCell(cell);
cell = new PdfPCell(new Phrase("Hello World"));
cell.PaddingLeft = 5f;
cell.Colspan = 1;
table.AddCell(cell);
cell = new PdfPCell(new Phrase("XYX"));
cell.Colspan = 2;
table.AddCell(cell);
table.SpacingBefore = 5f;
document.Add(table);
document.Close();
Response.ContentType = "application/pdf";
Response.AddHeader("Content-Disposition", "attachment;filename=Receipt-test.pdf");
Response.BinaryWrite(output.ToArray());
Do I need to specify no borders for individual cells or I can specify no borders for table itself.
Thank you
Although I upvoted the answer by Martijn, I want to add a clarification.
Only cells have borders in iText; tables don't have a border. Martijn's suggestion to set the border of the default cell to NO_BORDER is correct:
table.DefaultCell.Border = Rectangle.NO_BORDER;
But it won't work for the code snippet provided in the question. The properties of the default cell are only used if iText needs to create a PdfPCell instance implicitly (for instance: if you use the addCell() method passing a Phrase as parameter).
In the code snippet provided by #Brown_Dynamite, the PdfPCell objects are created explicitly. This means that you need to set the border of each of these cells to NO_BORDER.
Usually, I write a factory class to create cells. That way, I can significantly reduce the amount of code in the class that creates the table.
This should do the trick:
table.DefaultCell.Border = Rectangle.NO_BORDER;
or
table.borderwidth= 0;
First we can set all cell borders as 0 and After assigning all cell to table we can use the following code for for only pdfptable outer border.
PdfPCell cell = new PdfPCell();
cell.AddElement(t);
cell.BorderWidthBottom=1f;
cell.BorderWidthLeft=1f;
cell.BorderWidthTop=1f;
cell.BorderWidthRight = 1f;
PdfPTable t1 = new PdfPTable(1);
t1.AddCell(cell);
Here we can add table to one cell and can set border and again add that cell to another table and we can use as per our requirement.
If your PdfPTable is nested within another PdfPTable, the nested table will show table borders. The only way to get rid of the table borders is to put the nested PdfPTable into a PdfPCell of the main PdfPTable and set the border width of that cell to 0.
iTextSharp.text.pdf.PdfPTable table = new iTextSharp.text.pdf.PdfPTable(1); //<-- Main table
table.TotalWidth = 540f;
table.LockedWidth = true;
float[] widths = new float[] { 540f };
table.SetWidths(widths);
table.HorizontalAlignment = 1; //0=Left, 1=Centre, 2=Right
table.SpacingAfter = 10;
PdfPTable bodyTable = new PdfPTable(1); //<--Nested Table
bodyTable.TotalWidth = 540f;
bodyTable.LockedWidth = true;
float[] bodyWidths = new float[] { 540f };
bodyTable.SetWidths(bodyWidths);
bodyTable.HorizontalAlignment = 0;
bodyTable.SpacingAfter = 10;
bodyTable.DefaultCell.Border = iTextSharp.text.Rectangle.NO_BORDER;
var para1 = new Paragraph("This is a long paragraph", blackNormal);
para1.SetLeading(3f, 1f);
PdfPCell bodyCell1 = new PdfPCell();
bodyCell1.AddElement(para1);
bodyCell1.Border = 0;
bodyTable.AddCell(bodyCell1);
iTextSharp.text.pdf.PdfPCell cellBody = new iTextSharp.text.pdf.PdfPCell(bodyTable);
cellBody.BorderWidth = 0; //<--- This is what sets the border for the nested table
table.AddCell(cellBody);
Took me a long time to figure this out. It works for me now.
PdfPTable table = new PdfPTable(4);
table.TotalWidth = 400f;
table.LockedWidth = true;
PdfPCell header = new PdfPCell(new Phrase("Header"));
header.Colspan = 4;
table.AddCell(header);
table.AddCell("Cell 1");
table.AddCell("Cell 2");
table.AddCell("Cell 3");
table.AddCell("Cell 4");
PdfPTable nested = new PdfPTable(1);
nested.AddCell("Nested Row 1");
nested.AddCell("Nested Row 2");
nested.AddCell("Nested Row 3");
PdfPCell nesthousing = new PdfPCell(nested);
nesthousing.Padding = 0f;
table.AddCell(nesthousing);
PdfPCell bottom = new PdfPCell(new Phrase("bottom"));
bottom.Colspan = 3;
table.AddCell(bottom);
doc.Add(table);
PdfPTable table = new PdfPTable(3);
table.TotalWidth = 144f;
table.LockedWidth = true;
table.HorizontalAlignment = 0;
PdfPCell left = new PdfPCell(new Paragraph("Rotated"));
left.Rotation = 90;
table.AddCell(left);
PdfPCell middle = new PdfPCell(new Paragraph("Rotated"));
middle.Rotation = -90;
table.AddCell(middle);
table.AddCell("Not Rotated");
doc.Add(table);
Check this link pls
try this code
yourtable.DefaultCell.Border = 0;
Currently I using ITextSharp for exporting my gridview to pdf. My gridview have an Image file and it's width will expend to 125% and height also to 125% percent.
My questions are:
how do i set the image to widht:80px and height:100px.
after set the image width and height, how to insert it to the gridview?
besides that, after i export the gridview to pdf file, the image will go out of the cell. What is that and how to solve?
See this post in MikesDotnetting. Another post about working with tables in iTextsharp is also there
See a sample code for working with tables
// adding content to iTextSharp Document instance
PdfPTable table = new PdfPTable(3);
//actual width of table in points
table.TotalWidth = 500f;
//fix the absolute width of the table
table.LockedWidth = true;
//relative col widths in proportions
float[] widths = new float[] { 1f, 2f, 1f };
table.SetWidths(widths);
table.HorizontalAlignment = 0;
//leave a gap before and after the table
table.SpacingBefore = 20f;
table.SpacingAfter = 10f;
//Start Heading
table.AddCell(new PdfPCell() { BorderColor = BaseColor.LIGHT_GRAY, Phrase = new Phrase("No.", new Font(Font.FontFamily.HELVETICA, 8f, Font.BOLD)) });
table.AddCell(new PdfPCell() { BorderColor = BaseColor.LIGHT_GRAY, Phrase = new Phrase("Item Name", new Font(Font.FontFamily.HELVETICA, 8f, Font.BOLD)) });
table.AddCell(new PdfPCell() { BorderColor = BaseColor.LIGHT_GRAY, Phrase = new Phrase("Description", new Font(Font.FontFamily.HELVETICA, 8f, Font.BOLD)) });
// Table content
//Here we can use a loop to add multiple rows
table.AddCell(new PdfPCell() { BorderColor = BaseColor.LIGHT_GRAY, Phrase = new Phrase("1", new Font(Font.FontFamily.HELVETICA, 8f, Font.NORMAL)) });
table.AddCell(new PdfPCell() { BorderColor = BaseColor.LIGHT_GRAY, Phrase = new Phrase("Register Book"), new Font(Font.FontFamily.HELVETICA, 8f, Font.NORMAL)) });
table.AddCell(new PdfPCell() { BorderColor = BaseColor.LIGHT_GRAY, Phrase = new Phrase("Used to manage the details"), new Font(Font.FontFamily.HELVETICA, 8f, Font.NORMAL)) });
Here you can see a three column table. For adding multiple rows you can loop the table content part in the code.
Pass the values from code as shown.
I'm having a weird problem with images in iTextSharp library.
I'm adding the image to the PdfPCell and for some reason it gets scaled up.
How do i keep it to original size?
I though that the images would be same when printed but the difference on the pic is the same on the printed version. Having to manually scale the image with ScaleXXX to get it to right seems a bit illogical and does not give a good result.
So how do I put the image in its original size inside a PdfPCell of a table without having to scale it?
Here's my code:
private PdfPTable CreateTestPDF()
{
PdfPTable table = new PdfPTable(1);
table.WidthPercentage = 100;
Phrase phrase = new Phrase("MY TITLE", _font24Bold);
table.AddCell(phrase);
PdfPTable nestedTable = new PdfPTable(5);
table.WidthPercentage = 100;
Phrase cellText = new Phrase("cell 1", _font9BoldBlack);
nestedTable.AddCell(cellText);
cellText = new Phrase("cell 2", _font9BoldBlack);
nestedTable.AddCell(cellText);
cellText = new Phrase("cell 3", _font9BoldBlack);
nestedTable.AddCell(cellText);
iTextSharp.text.Image image = iTextSharp.text.Image.GetInstance(#"d:\MyPic.jpg");
image.Alignment = iTextSharp.text.Image.ALIGN_CENTER;
PdfPCell cell = new PdfPCell(image);
cell.HorizontalAlignment = PdfPCell.ALIGN_MIDDLE;
nestedTable.AddCell(cell);
cellText = new Phrase("cell 5", _font9BoldBlack);
nestedTable.AddCell(cellText);
nestedTable.AddCell("");
string articleInfo = "Test Text";
cellText = new Phrase(articleInfo, _font8Black);
nestedTable.AddCell(cellText);
nestedTable.AddCell("");
nestedTable.AddCell("");
nestedTable.AddCell("");
table.AddCell(nestedTable);
SetBorderSizeForAllCells(table, iTextSharp.text.Rectangle.NO_BORDER);
return table;
}
static BaseColor _textColor = new BaseColor(154, 154, 154);
iTextSharp.text.Font _font8 = new iTextSharp.text.Font(iTextSharp.text.Font.FontFamily.HELVETICA, 8, iTextSharp.text.Font.NORMAL, _textColor);
iTextSharp.text.Font _font8Black = new iTextSharp.text.Font(iTextSharp.text.Font.FontFamily.HELVETICA, 8, iTextSharp.text.Font.NORMAL, BaseColor.BLACK);
iTextSharp.text.Font _font9 = new iTextSharp.text.Font(iTextSharp.text.Font.FontFamily.HELVETICA, 9, iTextSharp.text.Font.NORMAL, _textColor);
iTextSharp.text.Font _font9BoldBlack = new iTextSharp.text.Font(iTextSharp.text.Font.FontFamily.HELVETICA, 9, iTextSharp.text.Font.BOLD, BaseColor.BLACK);
iTextSharp.text.Font _font10 = new iTextSharp.text.Font(iTextSharp.text.Font.FontFamily.HELVETICA, 10, iTextSharp.text.Font.NORMAL, _textColor);
iTextSharp.text.Font _font10Black = new iTextSharp.text.Font(iTextSharp.text.Font.FontFamily.HELVETICA, 10, iTextSharp.text.Font.NORMAL, BaseColor.BLACK);
iTextSharp.text.Font _font10BoldBlack = new iTextSharp.text.Font(iTextSharp.text.Font.FontFamily.HELVETICA, 10, iTextSharp.text.Font.BOLD, BaseColor.BLACK);
iTextSharp.text.Font _font24Bold = new iTextSharp.text.Font(iTextSharp.text.Font.FontFamily.HELVETICA, 24, iTextSharp.text.Font.BOLD, _textColor);
I'm using iTextSharp v4.1.2 and I get the following behavior:
Using this code, adding the image directly to the table via the AddCell method, the image is scaled up to fit the cell:
nestedTable.AddCell(image);
Using this code, adding the image to a cell, then adding the cell to the table, the image is displayed at its original size:
PdfPCell cell = new PdfPCell(image);
cell.HorizontalAlignment = PdfPCell.ALIGN_CENTER;
nestedTable.AddCell(cell);
Have you added the image directly to the pdf document (outside the table) just to compare/double-check the image sizes?
document.add(image);
I assume that you want the image centered in the cell with some space around it. As a last resort, you can change your image. Make it a png with a transparent background, and just make sure that there is some transparent 'margin' around all the edges of your image.
EDIT
I just downloaded the v5.0.2 and I get the same results as mentioned above. I've tried it with images that are both smaller and larger than the size of the cell, and the behavior is the same; the first method scales the image, the second method does not.
EDIT
Well, apparently I have been wrong for years about the whole DPI thing when it comes to images. I can't seem to see that it makes any difference at all what the DPI of the image is.
I created a 600x400px image at three different resolutions, 72dpi, 96 dpi, and 110 dpi. Then I added each these images to a new document that was exactly 600x400.
Dim pSize As Rectangle = New Rectangle(600, 1000)
Dim document As Document = New Document(pSize, 0, 0, 0, 0)
For each of the three image files, when added to the document with
document.add(image)
they fit the document perfectly, with no differences for the different DPI settings.
#Stewbob's answer does work, but it's only incidently related to the methods of the table.
The thing with iTextSharp is that it will behave differently depending on which constructor you use. This will (annoyingly) scale up the image to fill the cell:
PdfPCell c = new PdfPCell();
c.Add(image);
c.setHorizontalAlignment(Element.ALIGN_CENTER); // this will be ignored
But this will leave the image at the size you set it (and allow for alignment):
PdfPCell c = new PdfPCell(image);
c.setHorizontalAlignment(Element.ALIGN_CENTER);
I don't know exactly why this is, it's got something to do with the cell being in 'text mode' if you add the image in the constructor versus 'composite mode' if you add it later (in which case each object is supposed to look after it's own alignment).
Some more info (in Java, but still applies) http://tutorials.jenkov.com/java-itext/table.html#cell-modes
So if you have to mantain the size of the image in the PdfPCell you can loock at this code :
iTextSharp.text.Image image = iTextSharp.text.Image.GetInstance(imageFilePath);
// Save the image width
float width = image.Width;
PdfPCell cell = new PdfPCell();
cell.AddElement(image);
// Now find the Image element in the cell and resize it
foreach (IElement element in cell.CompositeElements)
{
// The inserted image is stored in a PdfPTable, so when you find
// the table element just set the table width with the image width, and lock it.
PdfPTable tblImg = element as PdfPTable;
if (tblImg != null)
{
tblImg.TotalWidth = width;
tblImg.LockedWidth = true;
}
}
The function has a property to fit image. Only add a true
cell.AddElement(image,true);
For those asking for the overload, use this :
var imageCell = new PdfPCell(image, true);
instead of :
cell.AddElement(image,true);