How do I place text at a specific location on the pdf? I did a little bit of searching but didn't find anything too good. I have document.Add(new Paragraph("Date:" + DateTime.Now)); and I wanted to place that on a specific area on the pdf file.
My code:
private void savePDF_Click(object sender, EventArgs e)
{
FileStream fileStream = new FileStream(nameTxtB.Text + "Repair.pdf", FileMode.Create, FileAccess.Write, FileShare.None);
Document document = new Document();
document.Open();
iTextSharp.text.Rectangle rectangle = new iTextSharp.text.Rectangle(PageSize.LETTER);
PdfWriter pdfWriter = PdfWriter.GetInstance(document, fileStream);
iTextSharp.text.Image r3tsLogo = iTextSharp.text.Image.GetInstance("rt3slogo.PNG"); //creates r3ts logo
iTextSharp.text.Image r3Info = iTextSharp.text.Image.GetInstance("R3 Information.PNG"); //creates r3 information text below r3ts logo
r3tsLogo.SetAbsolutePosition(document.PageSize.Width - 375 - 0f, document.PageSize.Height - 130 - 0f);
r3Info.SetAbsolutePosition(document.PageSize.Width - 365 - 0f, document.PageSize.Height - 170 - 0f); //higher the number in height the lower the place of text on paper
//less number will result in text more to right in width
//increase size of picture
r3tsLogo.ScalePercent(120);
r3Info.ScalePercent(65);
//---------------adds all images to pdf file ---------------------------------
document.Add(r3tsLogo);
document.Add(r3Info);
document.Add(new Paragraph("Date:" + DateTime.Now));
document.Close();
}
Assuming that you know how to add images at an absolute position (see Joris' answer), but looking at how to add text, then the answer to your question is: use ColumnText.
If you only need to add a single line that doesn't need to be wrapped, you can use the ShowTextAligned() method:
ColumnText.showTextAligned(writer.DirectContent,
Element.ALIGN_CENTER, new Phrase("single line"), x, y, rotation);
In this line of code, x and y are the coordinates for the middle of the text (other possible alignment values are ALIGN_LEFT and ALIGN_RIGHT). The rotation parameter defines a rotation in degrees. Note that the text "single line" won't be wrapped. You can add text that "falls off the page" this way if the text you're adding is too long.
If you want to add text inside a specific rectangle, then you need to define the column using a Rectangle object:
ColumnText ct = new ColumnText(writer.DirectContent);
ct.setSimpleColumn(new Rectangle(0, 0, 523, 50));
ct.addElement(new Paragraph("This could be a very long sentence that needs to be wrapped"));
ct.go();
If you provide more text than fits the rectangle, that text will not be rendered. However, it will still be available in the ct object so that you can add that remaining text at another position.
All of this has been asked and answered before:
Single line:
http://stackoverflow.com/questions/16370428/how-to-write-in-a-specific-location-the-zapfdingbatslist-in-a-pdf-document-using
http://stackoverflow.com/questions/17998306/rotating-text-using-center-in-itext
Multiple lines:
http://stackoverflow.com/questions/33609447
http://stackoverflow.com/questions/31152874/how-to-add-text-in-pdfcontentbyte-rectangle-using-itextsharp
http://stackoverflow.com/questions/15414923/rotate-paragraphs-or-cells-some-arbitrary-number-of-degrees-itext
Did I have to search long for these examples? No, I found them on the official web site under Absolute Positioning of text.
Wisdom is there for those who search...
This concept is thoroughly explained in the book 'iText in action'. Which can be found on the website.
http://developers.itextpdf.com/examples/itext-action-second-edition/chapter-3
Short code sample (check the site for other examples):
// step 1
Document document = new Document(PageSize.POSTCARD, 30, 30, 30, 30);
// step 2
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(RESULT));
// step 3
document.open();
// step 4
// Create and add a Paragraph
Paragraph p = new Paragraph("Foobar Film Festival", new Font(FontFamily.HELVETICA, 22));
p.setAlignment(Element.ALIGN_CENTER);
document.add(p);
// Create and add an Image
Image img = Image.getInstance(RESOURCE);
img.setAbsolutePosition(
(PageSize.POSTCARD.getWidth() - img.getScaledWidth()) / 2,
(PageSize.POSTCARD.getHeight() - img.getScaledHeight()) / 2);
document.add(img);
Related
I have a function which is cropping the specific part of the pdf file and adding it into the new Pdf file but the main problem that i am getting is that it is showing the cropped part of the page into the bottom (footer) of the newly created pdf file.
Here is the code..
public static void CropPdfFile(string sourceFilePath, string outputFilePath)
{
// Allows PdfReader to read a pdf document without the owner's password
PdfReader.unethicalreading = true;
// Reads the PDF document
using (PdfReader pdfReader = new PdfReader(sourceFilePath))
{
// Set which part of the source document will be copied.
// PdfRectangel(bottom-left-x, bottom-left-y, upper-right-x, upper-right-y)
PdfRectangle rect = new PdfRectangle(0f, 9049.172f, 594.0195f, 700.3f);
using (var output = new FileStream(outputFilePath, FileMode.CreateNew, FileAccess.Write))
{
// Create a new document
using (Document doc = new Document())
{
// Make a copy of the document
PdfSmartCopy smartCopy = new PdfSmartCopy(doc, output);
// Open the newly created document
doc.Open();
// Loop through all pages of the source document
for (int i = 4; i <= pdfReader.NumberOfPages; i++)
{
// Get a page
var page = pdfReader.GetPageN(i);
// Apply the rectangle filter we created
page.Put(PdfName.CROPBOX, rect);
page.Put(PdfName.MEDIABOX, rect);
// Copy the content and insert into the new document
smartCopy.SetLinearPageMode();
var copiedPage = smartCopy.GetImportedPage(pdfReader, i);
smartCopy.AddPage(copiedPage);
}
// Close the output document
doc.Close();
}
}
}
Please help me to solve this..
The size of a PDF page (expressed in user units) depends on the value of the mediabox. For instance: The media box of an A4 page is usually defined like this [0 0 595 842]
In this case, the origin of the coordinate system (0, 0) coincides with the lower-left corner. The coordinate of the upper right corner is (595, 842).
Another possible value for an A4 page would be [0 842 595 1684]. Same width (595 user units), same height (1684 - 842 = 842 user units), but the lower-left corner now has the coordinate (0, 842) and the coordinate of the upper-right corner is (595, 1684).
You write that you create a PdfRectangle using these parameters: (bottom-left-x, bottom-left-y, upper-right-x, upper-right-y). However, you're using these hard-coded values: 0f, 9049.172f, 594.0195f, 700.3f.
Your lower-left-y (9049.172) is at a higher position than your upper-right-y (700.3). This doesn't really make sense. Hence: you should consider changing that value to something that does make sense. What value that should be, is a question only you can answer since only you know the value of the MediaBox of the file you want to crop.
In your comment, you explain that your PDF is an A4 page. You can check this by using the PdfReader method named getPageSize(). If you want to crop the page so that you only see the header of your document, you need to use something like this:
PdfRectangle rect = new PdfRectangle(0f, 842 - x, 595, 842);
Where x is the height of the header. For instance, if the header is 100 user units, then you'd need:
PdfRectangle rect = new PdfRectangle(0f, 742, 595, 842);
It is unclear why you're always talking about 100px. If you want to convert pixels to points, please read Convert Pixels to Points
Using the formula mentioned there 100 pixels equals 75 points.
I need some help with tweaking my PDF header/footer alongside my text areas. The first page looks okay and it just gets worse from there. Is the header and footer eating into my existing margin spaces?
I would like to know what is going wrong and what I can tweak to set the below:
Page widths
Margin widths
Header
Footer
Text area
My header override function is as below:
public partial class Header : PdfPageEventHelper
{
public override void OnStartPage(PdfWriter writer, Document doc)
{
PdfPTable headerTbl = new PdfPTable(2);
headerTbl.SetWidths(new float[] { 4, 1 });
headerTbl.TotalWidth = doc.PageSize.Width;
iTextSharp.text.Image logo = iTextSharp.text.Image.GetInstance(HttpContext.Current.Server.MapPath("~/Images/view.gif"));
logo.ScalePercent(5);
PdfPCell cell = new PdfPCell(logo);
cell.HorizontalAlignment = Element.ALIGN_RIGHT;
cell.PaddingRight = 20;
cell.Border = Rectangle.NO_BORDER;
Font timesH = new Font(Font.FontFamily.TIMES_ROMAN, 20);
Font times = new Font(Font.FontFamily.TIMES_ROMAN, 10);
Chunk c1= new Chunk("THIS IS MY HEADER TEXT", timesH);
Chunk c = new Chunk("\n", times);
Chunk c2=new Chunk("PLEASE HAVE A NICE DAY", times);
Phrase p = new Phrase();
p.Add(c1);
p.Add(c);
p.Add(c2);
PdfPCell cell2 = new PdfPCell(p);
cell2.Border = Rectangle.NO_BORDER;
headerTbl.AddCell(cell2);
headerTbl.AddCell(cell);
headerTbl.WriteSelectedRows(0, -1, 0, (doc.PageSize.Height - 10), writer.DirectContent);
}
}
stringWrite is a StringWriter that contains a bunch of data. More clarity HERE.
I create the pdf as follows:
StringReader sr = new StringReader(stringWrite.ToString());
Document pdfDoc = new Document(new Rectangle(288f, 144f), 10f, 10f, 30f, 30f);
pdfDoc.SetPageSize(PageSize.A4.Rotate());
HTMLWorker htmlparser = new HTMLWorker(pdfDoc);
PdfWriter pdfwriter = PdfWriter.GetInstance(pdfDoc, HttpContext.Current.Response.OutputStream);
pdfwriter.PageEvent = new Footer();
pdfwriter.PageEvent = new Header();
pdfDoc.Open();
htmlparser.Parse(sr);
pdfDoc.Close();
HttpContext.Current.Response.Write(pdfDoc);
HttpContext.Current.Response.End();
I'm using iTextSharp, C#, Asp.net in my application.
You initialize the document creation with
Document pdfDoc = new Document(new Rectangle(288f, 144f), 10f, 10f, 30f, 30f);
This means especially that you reserve 10 units both left and right and 30 units both top and bottom as margin. The whole remaining inner space can be used by the automatic content layout mechanisms.
Header material, therefore, has to be drawn in that margin area, otherwise it may overlap with page content.
Your code, on the other hand, creates a paragraph with two lines, the first one set in a 20 unit font, the second one in a 10 unit font, and wraps it in a table. Thus, this table has a height of more than 30 units (the combined height of those two lines plus some inter-line space and possibly some table cell margin overhead). Then it draws it like this
headerTbl.WriteSelectedRows(0, -1, 0, (doc.PageSize.Height - 10), writer.DirectContent);
So it starts 10 units beneath the top of the page. You defined the top page margin to be merely 30, though. Thus, the header and the page content overlap in a stripe more than 10 units high.
Thus, I would propose you increase the top margin by 20 (more than ten plus some distance for the looks of it):
Document pdfDoc = new Document(new Rectangle(288f, 144f), 10f, 10f, 50f, 30f);
The reason why the first page looked all right most likely is that your HTML starts with some empty space (at least as far as the HTMLWorker is concerned).
Additional remarks:
Adding content in OnStartPage is discouraged. You should use OnEndPage for all such manipulations of the content, headers, footers, background images, ...
HTMLWorker is deprecated. You should use XMLWorker.
Is there a reason why you don't set the final page size from the start (in new Document) but instead separately?
Contextt: I am opening an existing, interactive PDF form containing AcroForm fields. I tried to add an image to a rectangle field in the PDF form like this:
string path = HttpContext.Current.Server.MapPath("includes");
string newFile = HttpContext.Current.Server.MapPath("Tmp") + "/completed_gray" +".pdf";
string imagepath = HttpContext.Current.Server.MapPath("Tmp");
Document doc = new Document();
try {
PdfWriter.GetInstance(doc, new FileStream(newFile, FileMode.Open));
doc.Open();
iTextSharp.text.Image gif = iTextSharp.text.Image.GetInstance(imagepath + "/CUstomRep_Eng_Col_1_V1.png");
iTextSharp.text.Rectangle rect = pdfStamper.AcroFields.GetFieldPositions("img_1_space")[0].position;
gif.ScaleAbsolute(rect.Width, rect.Height);
gif.SetAbsolutePosition(rect.Left, rect.Bottom);
doc.Add(gif);
}
catch (Exception ex) {
//Log error;
}
finally {
doc.Close();
}
The image doesn't show up in the resulting PDF.
You're creating a document using the "5 steps to create a PDF document" as documented in my books.
create a Document object.
create a PdfWriter instance.
open the document.
add content to the document.
close the document.
This contradicts with what you actually want to do: I want to add an Image in a placeholder defined by an AcroForm field.
Why are you saying you want one thing, and doing something else? Beats me. Probably because you didn't want to read the documentation.
You need something like this:
Create a PdfReader instance.
Create a PdfStamper instance.
Ask the stamper for information about the fields.
Add content to a page using the stamper instance.
Close the stamper.
In answer to your question: why doesn't my image show up in my document?
Support the coordinates of the field in the existing document are lower-left corner x = 600, y = 600 and upper-right corner x = 700, y = 700, then you are adding the image outside the visible area of the page you're creating. When you use new Document();, you're creating a document where the lower-left corner is x = 0, y = 0 and the upper-right corner is x = 595, y = 842.
In that case, you're adding the image to the document, but it's not visible because you've added it outside the rectangle that defines the page.
I am using a deprecated version of iTextSharp (4.1.6.0) to produce PDFs form my MVC3 application, and really need to be able to lay translucent shapes over the top of other shapes and images, the goal being to fade the colours of the image underneath it, or grey it out. I would have thought this would be as simple as setting the alpha channel when choosing a colour for the shapes fill, so i tried this:
Document doc = new Document();
PdfWriter writer = PdfWriter.GetInstance(doc, new FileStream(#"C:/Filepath/doc.pdf", FileMode.Create))
doc.Open();
PdfContentByte over = writer.DirectContent;
// draw shape to be faded out
over.Rectangle(10, 10, 50, 50);
over.SetColorFill(Color.BLUE);
over.Fill();
// draw shape over the top to do the fading (red so i can easily see where it is)
over.Rectangle(0, 0, 60, 60);
over.SetColorFill(new Color(255,0,0,150)); // rgba
over.Fill();
doc.Close();
I would expect this to draw two rectangles near the bottom left of the page, a small blue one overlaid with a larger red, translucent one, but the red one is not translucent!
So i did some googling and found this page, which is actually about iText not iTextSharp, where they suggest using PdfGstate to set the fill opacity like this:
PdfGState gstate = new PdfGState();
gstate.setFillOpacity(0.3);
but when i try that the gstate object has no method that is anything like .setFillOpacity()! If anyone can point me in the right direction I would be most grateful.
One of the rules of converting Java libraries to C# libraries is that all of the getXYZ and setXYZ methods should be converted to simple C# properties.
So gstate.setFillOpacity(0.3); will be come gstate.FillOpacity = 0.3f;
using (Document doc = new Document())
{
PdfWriter writer = PdfWriter.GetInstance(doc, new FileStream(#"mod.pdf", FileMode.Create));
doc.Open();
PdfContentByte over = writer.DirectContent;
over.SaveState();
over.Rectangle(10, 10, 50, 50);
over.SetColorFill(BaseColor.BLUE);
over.Fill();
PdfGState gs1 = new PdfGState();
gs1.FillOpacity = 0.5f;
over.SetGState(gs1);
over.Rectangle(0, 0, 60, 60);
over.SetColorFill(new BaseColor(255, 0, 0, 150));
over.Fill();
over.RestoreState();
doc.Close();
}
Is it possible to set a background image for a pdf page in ITextSharp?
Whats the correct way to define a background image for a pdf page? Is there a property of the document I set?
Or is it just like creating another image(my image has the dimensions of a A4 page)? If I add the background image as a normal image will I be able to place paragraphs over the top of the background image?
var document = new Document(PageSize.A4, 50, 50, 25, 25);
// Create a new PdfWrite object, writing the output to a MemoryStream
var output = new MemoryStream();
var writer = PdfWriter.GetInstance(document, output);
var logo = iTextSharp.text.Image.GetInstance(Server.MapPath("~/Images/test.jpg"));
logo.SetAbsolutePosition(0,0);
document.Add(logo);
// Will the following paragraph be ON TOP or below the background image?
// I am aiming for on top
document.Add( new Paragraph("sjfkkjdsfk") );
document.Close();
The logo is fine - it's just a regular image content on the page, not backgound img (like in HTML). To put content on top of that, you need to use Direct Content:
PdfContentByte over = writer.DirectContent;
over.SaveState();
over.BeginText();
over.SetFontAndSize(BaseFont.CreateFont(), 9);
over.ShowTextAligned(Element.ALIGN_LEFT, "Your Text", x, y, 0);
over.SetLineWidth(0.3f);
over.EndText();
over.RestoreState();
Please note the x and y cord are from the bottom left corner. The last parameter is for rotation.
Another tip: do a doc.NewPage(); if you want to start a new page with the image background, so the the text cord is on the new page.