How do i rotate multiline text in itextsahrp?
I have tried:
float x = 200;
float y = 100;
PdfContentByte cb = stamper.GetOverContent(i);
ColumnText ct = new ColumnText(cb);
ct.SetSimpleColumn(new Phrase(new Chunk("Test \n new", FontFactory.GetFont(FontFactory.HELVETICA, 18, iTextSharp.text.Font.NORMAL))),
x, reader.GetCropBox(i).Height -( y+400),500+x, y, 10, Element.ALIGN_LEFT | Element.ALIGN_TOP);
ct.Go();
ColumnText.ShowTextAligned(
cb, Element.ALIGN_CENTER,
new Phrase(new Chunk("Test \n new", FontFactory.GetFont(FontFactory.HELVETICA, 18, iTextSharp.text.Font.NORMAL))), x, reader.GetCropBox(i).Height-y, 12);
ct.SetSimpleColumn shows multilie text but how do I rotate it?
ColumnText.ShowTextAligned does not show multiline.
I don't have a C# environment on my machines, so I've written an example in Java, named AddRotatedTemplate. I have taken an existing PDF file with the words "Hello World", I've created a template/XObject with some text, and I've added that template/XObject twice using the addTemplate() method (once using only x, y coordinates and once using parameters that rotate the text with PI / 4 grades). As a result, the text added to the template is added twice; see hello_template.pdf).
This is the code:
public void manipulatePdf(String src, String dest) throws IOException, DocumentException {
PdfReader reader = new PdfReader(src);
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest));
// Get canvas for page 1
PdfContentByte cb = stamper.getOverContent(1);
// Create template (aka XOBject)
PdfTemplate xobject = cb.createTemplate(80, 120);
// Add content using ColumnText
ColumnText column = new ColumnText(xobject);
column.setSimpleColumn(new Rectangle(80, 120));
column.addElement(new Paragraph("Some long text that needs to be distributed over several lines."));
column.go();
// Add the template to the canvas
cb.addTemplate(xobject, 36, 600);
double angle = Math.PI / 4;
cb.addTemplate(xobject,
(float)Math.cos(angle), -(float)Math.sin(angle),
(float)Math.cos(angle), (float)Math.sin(angle),
150, 600);
stamper.close();
reader.close();
}
There may be easier ways to define the rotation in other variations of the addTemplate() method, but I'm an engineer and I am so used to using the transformation matrix that I never feel the need or desire to use any other type of method.
Related
I have an existing PDF file, I want to insert a text at the bottom of PDF file in Red color, but the existing pdf file color must remain the same.
Thank You #mkl below code, I used which is specific for Stamp.
public static void ManipulatePdf(string src, string dest)
{
src = #"C:\CCPR Temp\TempFiles\PayStub_000106488_12282019_20200117112403.pdf";
dest = #"C:\CCPR Temp\TempFiles\PayStub_WithStamper.pdf";
PdfReader reader = new PdfReader(src);
PdfStamper stamper = new PdfStamper(reader, new FileStream(dest, FileMode.Create)); // create?
int numberOfPages = reader.NumberOfPages;
Rectangle pagesize;
for (int i = 1; i <= numberOfPages; i++)
{
PdfContentByte under = stamper.GetUnderContent(i);
pagesize = reader.GetPageSize(i);
float x =40;// (pagesize.Left + pagesize.Right) / 2;
float y = pagesize.Top/4;// (pagesize.Bottom + pagesize.Top) / 2;
PdfGState gs = new PdfGState();
gs.FillOpacity = 1.0f;
under.SaveState();
under.SetGState(gs);
under.SetRGBColorFill(255,0,0);
ColumnText.ShowTextAligned(under, Element.ALIGN_BOTTOM,
new Phrase("Watermark", new Font(Font.FontFamily.HELVETICA, 20)),
x, y, 1);
under.RestoreState();
}
stamper.Close();
reader.Close();
}
Adding content to an existing PDF document without changing the existing content, is sometimes referred to as stamping. Examples are adding page numbers, adding a watermark, and adding a running head.
For your specific case:
Create a PdfDocument instance from a PdfReader (to read the input PDF) and a PdfWriter (to write the output PDF). The PdfDocument instance will be in stamping mode.
Set the red text color on a Paragraph with the footer text.
Position the text with the ShowTextAligned convenience method, based on the page size.
You may also want to take into account page rotation.
PdfDocument pdfDoc = new PdfDocument(new PdfReader("input.pdf"), new PdfWriter("output.pdf"));
Document doc = new Document(pdfDoc);
Paragraph footer = new Paragraph("This is a footer").SetFontColor(ColorConstants.RED);
for (int i = 1; i <= pdfDoc.GetNumberOfPages(); i++)
{
Rectangle pageSize = pdfDoc.GetPage(i).GetPageSize();
float x = pageSize.GetLeft() + pageSize.GetWidth() / 2;
float y = pageSize.GetBottom() + 20;
doc.ShowTextAligned(footer, x, y, i, TextAlignment.CENTER, VerticalAlignment.BOTTOM, 0);
}
doc.Close();
This will set the Font of your Paragraph. I am not sure about the Position.
BaseFont btnRedFooter = BaseFont.CreateFont(BaseFont.TIMES_ROMAN, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
iTextSharp.text.Font fntRedFooter = FontFactory.GetFont(iTextSharp.text.Font.FontFamily.TIMES_ROMAN.ToString(), 16,
iTextSharp.text.Font.BOLD, iTextSharp.text.BaseColor.RED);
pProtocoll.Add(new Paragraph("Text in Footer", fntRedFooter));
I used the below steps and finally, got the required output. I was struggling for the font color, to apply to the newly added text.
public static void StampPdfFile(string oldFile, string newFile)
{
// open the reader
PdfReader reader = new PdfReader(oldFile);
Rectangle size = reader.GetPageSizeWithRotation(1);
Document document = new Document(size);
// open the writer
FileStream fs = new FileStream(newFile, FileMode.Create, FileAccess.Write);
PdfWriter writer = PdfWriter.GetInstance(document, fs);
document.Open();
// the pdf content
PdfContentByte cb = writer.DirectContent;
// select the font properties
BaseFont bf = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
cb.SetFontAndSize(bf, 8);
// write the text in the pdf content
cb.BeginText();
string text = $"Voided On - {DateTime.Now.Date.ToString("MM/dd/yyyy")}";
// put the alignment and coordinates here
cb.SetColorFill(BaseColor.RED); //Give Red color to the newly added Text only
cb.ShowTextAligned(2, text, 120, 250, 0);
cb.SetColorFill(BaseColor.BLACK); //Give Red color to the exisitng file content only
cb.EndText();
// create the new page and add it to the pdf
PdfImportedPage page = writer.GetImportedPage(reader, 1);
cb.AddTemplate(page, 0, 0);
document.Close();
fs.Close();
writer.Close();
reader.Close();
}
So I'm applying a canvas stroke to my pdf, but the stroke is applying to the cell text. But only the first cell.
Here is the method to draw the page border:
protected void DrawPageBorder(PdfWriter writer, Document document, PdfContentByte canvas)
{
var pageBorderRect = new Rectangle(document.PageSize);
var content = writer.DirectContent;
pageBorderRect.Left += document.LeftMargin - BorderDifference;
pageBorderRect.Right -= document.RightMargin - BorderDifference;
pageBorderRect.Top -= document.TopMargin - BorderDifference;
pageBorderRect.Bottom += document.BottomMargin - BorderDifference;
content.SetLineDash(3f, 3f);
content.SetRGBColorStroke(236, 236, 236);
//canvas.SetLineWidth(FillOpacity);
//canvas.SetRGBColorStroke(0, 0, 0);
//canvas.SetRGBColorStroke(236, 236, 236);
//canvas.SetLineDash(3f, 3f);
content.Rectangle(pageBorderRect.Left, pageBorderRect.Bottom, pageBorderRect.Width, pageBorderRect.Height);
content.Stroke();
}
this is the code which adds the pdf table with the border:
var docTable = new PdfPTable(1);
docTable.WidthPercentage = 100f;
PdfContentByte canvas = new PdfContentByte(pdfWriter);
DrawPageBorder(pdfWriter, doc, canvas);
This is the code to add the first table cell:
titleFont.Size = 24.0f;
var text1 = new PdfPCell(new Phrase("To:", titleFont))
{
HorizontalAlignment = Element.ALIGN_LEFT,
Border = Rectangle.NO_BORDER,
PaddingTop = 20f,
PaddingLeft = 9f,
PaddingRight = 9f
};
docTable.AddCell(text1);
Anyone know where I'm going wrong here?
Thanks
Whenever you mix high level api content creating (like you do with the table) and low level api drawing (like you do in DrawPageBorder), make sure your low level code does not leave behind any change to graphics state parameters.
Your code leaves changes to the LineDash and the stroking color.
You can do so by wrapping your code drawing on content in a safe-graphics-state / restore-graphics-state envelop.
In your case:
content.SaveState();
content.SetLineDash(3f, 3f);
content.SetRGBColorStroke(236, 236, 236);
//canvas.SetLineWidth(FillOpacity);
//canvas.SetRGBColorStroke(0, 0, 0);
//canvas.SetRGBColorStroke(236, 236, 236);
//canvas.SetLineDash(3f, 3f);
content.Rectangle(pageBorderRect.Left, pageBorderRect.Bottom, pageBorderRect.Width, pageBorderRect.Height);
content.Stroke();
content.RestoreState();
At the moment I'm trying to change the fonts used in a PDF document.
I therefore declared rectangles and extract the text using LocationTextExtractionStrategy:
System.util.RectangleJ rect = new System.util.RectangleJ(fX, fY, fWidth, fHeight);
RenderFilter[] rfArea = { new RegionTextRenderFilter(rect) };
ITextExtractionStrategy str = new FilteredTextRenderListener(new LocationTextExtractionStrategy(), rfArea);
string s = PdfTextExtractor.GetTextFromPage(reader, 1, str);
This works as expected, although it's quite complicated to find the right coordinates.
But how do I place the text in a new PDF document at the same starting location fX, fY so I don't break the layout?
I tried it using ColumnText but a multiline text is put one above the other:
Paragraph para = new Paragraph(fLineSpacing, s, font);
para.IndentationLeft = fLineIndentionLeft;
para.SpacingAfter = fSpacingAfter;
para.SpacingBefore = fSpacingBefore;
para.Alignment = iFontAlignment;
PdfContentByte cb = writer.DirectContent;
ColumnText ct = new ColumnText(cb);
ct.SetSimpleColumn(para, fX, fY + fHeight, fWidth + fX, fY, 0f, Element.ALIGN_LEFT);
ct.Go();
What am I missing? Or is there even something simpler? Using my approach I will have to cover the entire page defining lots of rectangles.
I have an existing PDF (not with form fields - more of a scanned document), and am using PdfReader to load the PDF "template" so that I write text on it.
For position simple fields I am using:
PdfReader reader = new PdfReader(templatePath);
Chunk chunk = new Chunk(text, fontToUse);
Phrase phrase = new Phrase();
phrase.Add(chunk);
PdfContentByte canvas = this.PdfWriter.DirectContent;
ColumnText.ShowTextAligned(this.PdfContentByte, alignment, phrase, left, top, 0);
I also need to write some text to a specific area which is a 400 x 200 rectangle. Since the size of the text varies, it may or may not fit into the rectangle.
Is there a way to write text to the rectangle, and if the text is too large for it to simply not appear (like overflow hidden would work in HTML)?
Got it!
Phrase myText = new Phrase(text);
PdfPTable table = new PdfPTable(1);
table.TotalWidth = 300;
table.LockedWidth = true;
PdfPCell cell = new PdfPCell(myText);
cell.Border = 0;
cell.FixedHeight = 40;
table.AddCell(cell);
table.WriteSelectedRows
(
0,
-1,
300,
700,
writer.DirectContent
);
I want to create a custom page size which is (5"X2") PDF using iTextSharp in C#. Is there any way to do this?
Document doc = new Document(iTextSharp.text.PageSize.A4, 15, 15, 0, 0);
Below code will demonstrate how to implement the custom PDF using PDF coordinates in C#.net. For this task you must aware about the pdf coordinates.
BaseFont f_cn;
string poath = Server.MapPath("~/fonts/CALIBRI.TTF");
f_cn = BaseFont.CreateFont(poath, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
using (System.IO.FileStream fs = new FileStream(Server.MapPath("~/TempPdf") + "\\" + "download.pdf", FileMode.Create))
{
Document document = new Document(PageSize.A4, 25, 25, 30, 30);
PdfWriter writer = PdfWriter.GetInstance(document, fs);
Paragraph p = new Paragraph();
// Add meta information to the document
document.AddAuthor("Mikael Blomquist");
document.AddCreator("Sample application using iTestSharp");
document.AddKeywords("PDF tutorial education");
document.AddSubject("Document subject - Describing the steps creating a PDF document");
document.AddTitle("The document title - Amplified Resource Group");
// Open the document to enable you to write to the document
document.Open();
// Makes it possible to add text to a specific place in the document using
// a X & Y placement syntax.
PdfContentByte cb = writer.DirectContent;
cb.SetFontAndSize(f_cb, 16);
// First we must activate writing
cb.BeginText();
// Add an image to a fixed position from disk
iTextSharp.text.Image png = iTextSharp.text.Image.GetInstance(Server.MapPath("~/images/arg.png"));
png.SetAbsolutePosition(200, 738);
cb.AddImage(png);
writeText(cb, "Header", 30, 718, f_cb, 14);
}
private void writeText(PdfContentByte cb, string Text, int X, int Y, BaseFont font, int Size)
{
cb.SetFontAndSize(font, Size);
cb.ShowTextAligned(PdfContentByte.ALIGN_LEFT, Text, X, Y, 0);
}
The document also accept the rectangle type, so we can create a rectangle of our custom size like below.
var pgSize = new iTextSharp.text.Rectangle(1000, 1000);
Document document = new Document(pgSize, 5f, 5f, 20f, 20f);