I am not sure how to add this text to the canvas in iText7. In the old version I use this BaseFont.CreateFont and overContent. In iText7 I see this PdfCanvas control and this PdfCanvas.BeginText mehtod but I am getting a error related to no overoad.
PdfPage pdfPage = pdfDocument.GetPage(i);
Rectangle pageSizeWithRotation = pdfPage.GetPageSizeWithRotation();
PdfCanvas canvas = new PdfCanvas(pdfPage);
Text pdfText = new Text(disclaimerText)
.SetFontColor(ColorConstants.BLACK)
.SetFont(PdfFontFactory.CreateFont(StandardFonts.HELVETICA, "Cp1250"))
.SetFontSize(7F);
canvas.BeginText(pdfText);
Old Version I have something like this
PdfContentByte overContent = pdfStamper.GetOverContent(i);
overContent.BeginText();
BaseFont baseFont = BaseFont.CreateFont("Helvetica", "Cp1250", false);
overContent.SetFontAndSize(baseFont, 7F);
overContent.SetRGBColorFill(0, 0, 0);
float n2 = 15F;
float n3 = pageSizeWithRotation.Height - 10F;
overContent.ShowTextAligned(0, disclaimerText, n2, n3, 0F);
overContent.EndText();
You can refer to the following code to understand how the BeginText and EndText work together with PdfCanvas.
//Get the page from the pdf
PdfPage page = pdfDoc.GetPage(i);
Rectangle pageSize = page.GetPageSizeWithRotation();
int pageNumber = pdfDoc.GetPageNumber(page);
PdfCanvas pdfCanvas = new PdfCanvas(page.NewContentStreamBefore(), page.GetResources(), pdfDoc);
//Set background
Color limeColor = new DeviceCmyk(0.208 f, 0, 0.584 f, 0);
Color blueColor = new DeviceCmyk(0.445 f, 0.0546 f, 0, 0.0667 f);
pdfCanvas.SaveState()
.SetFillColor(pageNumber % 2 == 1 ? limeColor : blueColor)
.Rectangle(pageSize.GetLeft(), pageSize.GetBottom(),
pageSize.GetWidth(), pageSize.GetHeight())
.Fill()
.RestoreState();
//Add header and footer
pdfCanvas.BeginText()
.SetFontAndSize(PdfFontFactory.CreateFont(StandardFonts.HELVETICA), 9)
.MoveText(pageSize.GetWidth() / 2 - 60, pageSize.GetTop() - 20)
.ShowText("THE TRUTH IS OUT THERE")
.MoveText(60, -pageSize.GetTop() + 30)
.ShowText(pageNumber.ToString())
.EndText();
//Add watermark
iText.Layout.Canvas canvas = new iText.Layout.Canvas(pdfCanvas, pdfDoc, page.GetPageSize());
canvas.SetProperty(Property.FONT_COLOR, Color.WHITE);
canvas.SetProperty(Property.FONT_SIZE, 60);
canvas.SetProperty(Property.FONT, PdfFontFactory.CreateFont(StandardFonts.HELVETICA_BOLD));
canvas.ShowTextAligned(new Paragraph("CONFIDENTIAL"), 298, 421, pdfDoc.GetPageNumber(page), TextAlignment.CENTER, VerticalAlignment.MIDDLE, 45);
pdfCanvas.Release();
This example is also available here in the knowledge base of iText 7 at https://kb.itextpdf.com/home/it7kb/examples/itext-7-jump-start-tutorial-chapter-3 example "c03e03_ufo"
Related
How do you change the DocumentRenderer in iText7 and continue on the corect position? I need some paragraphs to be rendered in 2 columns, and then normal text.
This is what I have, but it not works as expected:
using (MemoryStream oDocumentStream = new MemoryStream())
{
using (PdfWriter oDocumentWriter = new PdfWriter(oDocumentStream).SetSmartMode(true))
{
PdfDocument pdfDocument = new PdfDocument(oDocumentWriter);
Document document = new Document(pdfDocument);
float offSet = 60;
float columnWidth = (PageSize.A4.GetWidth() - offSet * 2 + 10) / 2;
float columnHeight = PageSize.A4.GetHeight() - offSet * 2;
//Define column areas
Rectangle[] columns = new Rectangle[]
{
new Rectangle(offSet - 5, offSet, columnWidth, columnHeight),
new Rectangle(offSet + columnWidth, offSet, columnWidth, columnHeight)
};
document.SetRenderer(new ColumnDocumentRenderer(document, columns)); //First renderer
document.Add(*myparagraph*);
document.SetRenderer(new iText.Layout.Renderer.DocumentRenderer(document)); //Second renderer
document.Add(*myparagraph*);
document.Close();
}
oPdfFile = oDocumentStream.ToArray();
}
The issue with this approach is that the second renderer don't continue where the first renderer ended, therefore they overlap, as you can see in this image:
I want to add text into every page of my pdf which is rotaded from bottom to top.
Like this:
Here is my code:
PdfDocument srcDocument = new PdfDocument(new PdfReader(file));
PdfDocument destDocument = new PdfDocument(new PdfWriter(newfile));
int pagesCount = srcDocument.GetNumberOfPages();
for (int i = 1; i <= pagesCount; i++)
{
srcDocument.CopyPagesTo(i, i, destDocument);
PdfCanvas pdfCanvas = new PdfCanvas(srcDocument.GetPage(i));
}
srcDocument.Close();
destDocument.Close();
In this I got stuck. I don't know how to go further : write and rotate text.
So, as per the comments on the original question, you basically need to print on a Canvas object, and rotate the Paragraph. The Rectangle basically defines the coordinates where you will place the Canvas. Something like this should work:
PdfDocument srcDocument = new PdfDocument(new PdfReader(file));
PdfDocument destDocument = new PdfDocument(new PdfWriter(newfile));
FontProgram fontProgram =
FontProgramFactory.CreateFont(#"C:\temp\calibri.ttf");
PdfFont calibri = PdfFontFactory.CreateFont(fontProgram, PdfEncodings.WINANSI);
int pagesCount = srcDocument.GetNumberOfPages();
for (int i = 1; i <= pagesCount; i++)
{
srcDocument.CopyPagesTo(i, i, destDocument);
PdfCanvas pdfCanvas = new PdfCanvas(destDocument.GetPage(i));
Canvas canvas = new Canvas(pdfCanvas, new Rectangle(36, 750, 100, 50));
canvas.Add(new Paragraph("0001").SetRotationAngle(1.5708).SetFont(calibri).SetFontSize(4));
canvas.Close();
}
srcDocument.Close();
destDocument.Close();
Alternatively, you can set a Style, if you plan on reusing a lot, something like:
Style rotatedStuff = new Style()
.SetRotationAngle(1.5708)
.SetFont(calibri)
.SetFontSize(4);
and then just apply it to the Paragraph with the AddStyle() method.
Mind you that if you provide with a float number, it's in rads, so 90° is 1.5708 rad (1 Degree (°) = 0.01745 Radian (rad)).
I am adding footer text to existing BYTES in each page using the code shown below, which is visible in Chrome as well as in Foxit PhantomPDF, however, it's not visible in Adobe PDF reader.
In addition to the footer, I also add headers which are visible even with Adobe.
private byte[] AddPageHeaderFooter(byte[] pdf, float marginLeft, float marginRight, float marginTop,
float marginBottom, DataSet prospectDetails, ref int startingPageNumber, string logoPath, bool isLandscape = false)
{
var dataRow = prospectDetails.Tables[0].Rows[0];
var prospectDate = Convert.ToDateTime(dataRow[0]);
using (var stream = new MemoryStream())
{
stream.Write(pdf, 0, pdf.Length);
var reader = new PdfReader(pdf);
var document = new Document(reader.GetPageSizeWithRotation(1), marginLeft, marginRight, marginTop,
marginBottom);
var writer = PdfWriter.GetInstance(document, stream);
document.Open();
var contentByte = writer.DirectContent;
var pageIndex = startingPageNumber;
for (var page = 1; page <= reader.NumberOfPages; page++)
{
document.NewPage();
pageIndex++;
var importedPage = writer.GetImportedPage(reader, page);
if (isLandscape)
contentByte.AddTemplate(importedPage, 0, -1f, 1f, 0, 0,
reader.GetPageSizeWithRotation(page).Height);
else
contentByte.AddTemplate(importedPage, 0, 0);
contentByte.BeginText();
var baseFont = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
// Code to add header
// Footer
// Not visible parts **START**
contentByte.SetFontAndSize(baseFont, 7);
var prospectDateString = string.Format("{0:ddd, MMM d, yyyy}", prospectDate);
contentByte.ShowTextAligned(PdfContentByte.ALIGN_CENTER,
"FOOTER LINE 1",
isLandscape ? 398 : 305f, 50, 0);
contentByte.ShowTextAligned(PdfContentByte.ALIGN_CENTER,
"FOOTER LINE 2", isLandscape ? 398 : 305f, 42, 0);
contentByte.ShowTextAligned(PdfContentByte.ALIGN_LEFT,
prospectDateString.Substring(5, prospectDateString.Length - 5), document.Left, marginBottom, 0);
contentByte.ShowTextAligned(PdfContentByte.ALIGN_CENTER, "- " + pageIndex + " -",
isLandscape ? 398 : 305f, marginBottom, 0);
contentByte.ShowTextAligned(PdfContentByte.ALIGN_RIGHT, string.Format("{0:T}", prospectDate),
document.Right, marginBottom, 0);
contentByte.EndText();
contentByte.SaveState();
// Not visible parts **END**
// Footer line
// Not visible parts **START**
contentByte.SetColorStroke(new PdfSpotColor("black", new BaseColor(0, 0, 0)), 100);
contentByte.SetLineWidth(0.25f);
contentByte.Rectangle(marginLeft, 58, isLandscape ? 732 : 552, 0.25f);
contentByte.FillStroke();
// Not visible parts **END**
contentByte.RestoreState();
}
startingPageNumber = pageIndex;
document.Close();
return stream.ToArray();
}
}
Issue:
Only the footer line that I draw is visible in Adobe.
Footer texts namely, footer line 1, footer line 2, Date as well as page number is not visible even when I try to print the document.
Screenshot:
I'm signing a document with token certificate:
var cp = new Org.BouncyCastle.X509.X509CertificateParser();
var chain = new[] { cp.ReadCertificate(cert.RawData) };
var externalSignature = new X509Certificate2Signature(cert, "SHA-1");
var pdfReader = new PdfReader(origem);
var signedPdf = new FileStream(destino, FileMode.Create);
var pdfStamper = PdfStamper.CreateSignature(pdfReader, signedPdf, '\0');
var sig = pdfStamper.SignatureAppearance;
sig.SetVisibleSignature(new Rectangle(50, 0, 500, 50), pdfReader.NumberOfPages, "Signature");
sig.SignatureRenderingMode = PdfSignatureAppearance.RenderingMode.DESCRIPTION;
sig.Layer2Text = "Assinado digitalmente por " + cert.SubjectName.Name;
sig.Layer2Font = new Font(Font.FontFamily.TIMES_ROMAN, 7);
MakeSignature.SignDetached(sig, externalSignature, chain, null, null, null, 0, CryptoStandard.CMS);
The signature text is rendered at bottom of the page. How can I change to a vertical mode, in the right part of document, outside the content margins?
thanks
First of all, to get some vertically oriented signature, the rectangle in which to visualize the signature should be somewhat more vertically oriented. Thus, in place of your
sig.SetVisibleSignature(new Rectangle(50, 0, 500, 50), pdfReader.NumberOfPages, "Signature");
you should use something like
sig.SetVisibleSignature(new Rectangle(50, 0, 50, 500), pdfReader.NumberOfPages, "Signature");
Now you clarified in comments that not only the visualization rectangle should have a vertical orientation but that the text also should be drawn vertically. iText by default creates visualizations with horizontal text. Thus, you have to use customized appearances.
As I am more at home with iText/Java, this example to customize a PdfSignatureAppearance appearance is in Java. It should be easy to transform to iTextSharp/C#, though.
appearance.setVisibleSignature(rectangle, PAGENUMBER, SIGNATURENAME);
// customize appearance layer 2 to display text vertically
PdfTemplate layer2 = appearance.getLayer(2);
layer2.transform(new AffineTransform(0, 1, -1, 0, rectangle.getWidth(), 0));
Font font = new Font();
font.setColor(BaseColor.WHITE);
font.setSize(10);
ColumnText ct2 = new ColumnText(layer2);
ct2.setRunDirection(PdfWriter.RUN_DIRECTION_NO_BIDI);
ct2.setSimpleColumn(new Phrase("Signed by me, myself and I", font), 0, 0, rectangle.getHeight(), rectangle.getWidth(), 15, Element.ALIGN_CENTER);
ct2.go();
This example draws "Signed by me, myself and I" vertically in the page area rectangle.
public bool drawVerticalText(string _text, Color _color, int _angle, int _size, int _left, int _top)
{
try
{
BaseColor bc = new BaseColor(_color.R, _color.G, _color.B, _color.A);
PdfContentByte cb = writer.DirectContent;
BaseFont bf = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.WINANSI, BaseFont.EMBEDDED);
//int width = baseFont.GetWidth(_text);
cb.BeginText();
cb.SetColorFill(CMYKColor.RED);
cb.SetFontAndSize(bf, _size);
cb.ShowTextAligned(PdfContentByte.ALIGN_CENTER, _text, _left, document.Top - _top, _angle);
cb.EndText();
document.Close();
return true;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
return false;
}
}
You can change the alpha value of the color, rotation angle (say, 45), text size and make a watermark to your document...
While above method uses DirectContent with absolute coordinates, the below method uses cell object with rotation property. Note that cell rotation can be multiple of 90, while with the 1st method you can have any angle...
public void drawVerticalText2()
{
PdfPTable table = new PdfPTable(4);
float[] widths = new float[] { 1.25f, 1.55f, 0.35f, 0.35f };
table.SetWidths(widths);
PdfPCell horizontalCell = new PdfPCell(new Phrase("I'm horizontal"));
horizontalCell.Border = BORDERS.BOX;
horizontalCell.HorizontalAlignment = 1;
table.AddCell(horizontalCell);
PdfPCell horizontalMirroredCell = new PdfPCell(new Phrase("I'm horizontal mirrored"));
horizontalMirroredCell.Border = BORDERS.BOX;
horizontalMirroredCell.HorizontalAlignment = 1;
horizontalMirroredCell.Rotation = 180;
table.AddCell(horizontalMirroredCell);
PdfPCell verticalCell = new PdfPCell(new Phrase("I'm vertical"));
verticalCell.Border = BORDERS.BOX;
verticalCell.HorizontalAlignment = 1;
verticalCell.Rotation = 90;
table.AddCell(verticalCell);
PdfPCell verticalMirroredCell = new PdfPCell(new Phrase("I'm vertical mirrored"));
verticalMirroredCell.Border = BORDERS.BOX;
verticalMirroredCell.HorizontalAlignment = 1;
verticalMirroredCell.Rotation = -90;
table.AddCell(verticalMirroredCell);
table.SpacingBefore = 20f;
table.SpacingAfter = 30f;
document.Add(table);
document.Close();
}
enjoy!
I have researched this and tried to rotate a single page PDF's contents. I am able to rotate the page 90, 180 or 270 degrees. I don't want to rotate the page but rather the contents.
Here's the method I have adapted so far:
public static byte[] RotatePdf(byte[] fileBytes, int degreesClockwise)
{
if (degreesClockwise % 90 != 0)
throw new ApplicationException(string.Format("degreesClockwise must be 0, 90, 180, 360: {0}", degreesClockwise));
PdfReader reader = new PdfReader(fileBytes);
using (var fs = new MemoryStream())
{
PdfStamper stamper = new PdfStamper(reader, fs);
PdfDictionary pageDict = reader.GetPageN(1);
int desiredRotation = degreesClockwise; // x degrees clockwise from what it is now
PdfNumber rotation = pageDict.GetAsNumber(PdfName.ROTATE);
if (rotation != null)
{
desiredRotation += rotation.IntValue;
desiredRotation %= 360; // must be 0, 90, 180, or 270
}
pageDict.Put(PdfName.ROTATE, new PdfNumber(desiredRotation));
stamper.Close();
return fs.ToArray();
}
}
Any suggestions would be greatly appreciated.
I accomplished the code using the PdfSharp library as I could not find any examples or answers for iTextSharp unfortunately.
Here is the code I used to accomplish what I wanted:
// Create the output document
PdfDocument outputDocument = new PdfDocument();
// Show single pages
// (Note: one page contains two pages from the source document)
outputDocument.PageLayout = PdfPageLayout.SinglePage;
// Open the external document as XPdfForm object
XPdfForm form = XPdfForm.FromFile(filename);
for (int i = 0; i < form.PageCount; i++)
{
// Add a new page to the output document
PdfPage page = outputDocument.AddPage();
page.Orientation = PageOrientation.Landscape;
double width = page.Width;
double height = page.Height;
int rotate = page.Elements.GetInteger("/Rotate");
XGraphics gfx = XGraphics.FromPdfPage(page);
XRect box = new XRect(0, 0, width, height * 2);
// Draw the page identified by the page number like an image
gfx.DrawImage(form, box);
}
// Save the document...
filename = "RotatedAndStretched_tempfile.pdf";
outputDocument.Save(filename);