I need your help in positioning some text to specific location in the line rather than using left, center or right alignment in PDFCell. I have some text that needs to be aligned after the center of the PDFCell. Currently, the code is aligning the text to the center, however I need to give it more spaces to the right:
PdfPTable table = new PdfPTable(1);
PdfPCell cell = new PdfPCell(new Paragraph("\u0625\u0644\u0649 \u0645\u0646 \u064a\u0647\u0645\u0647 \u0627\u0644\u0623\u0645\u0631",font));
table.setRunDirection(PdfWriter.RUN_DIRECTION_RTL);
table.getDefaultCell().setBorder(Rectangle.NO_BORDER);
cell.setBorder(Rectangle.NO_BORDER);
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
table.addCell(cell);
doc.add(table);
So how can I achieve this.
I managed it by creating a function that creates spaces and append it to the paragraph:
String addspace(int i, String str) {
StringBuilder str1 = new StringBuilder();
for (int j = 0; j < i; j++) {
str1.append(" ");
}
str1.append(str);
return str1.toString();
}
Related
I want to print a DHL label using a label printer.
The DHL label consists of 2 parts: The left half of the image is just info that I can keep to myself. The right part of the PDF is what should actually be printed.
I would therefore like to cut away the left part of the PDF.
I do not want to make it blank, but I really I want to cut if off.
How could I do this?
You essentially want to cut away one half of the PDF page; looking at you screenshot most likely the lower half.
Using iTextSharp 5.5.13.3 you can do that like this:
var testFile = #"new pdf1.pdf";
var resultFile = #"new pdf1-Cut.pdf";
using (PdfReader pdfReader = new PdfReader(testFile))
using (PdfStamper pdfStamper = new PdfStamper(pdfReader, File.Create(resultFile)))
{
for (int i = 1; i <= pdfReader.NumberOfPages; i++)
{
Rectangle cropBox = pdfReader.GetCropBox(i);
PdfArray newCropBox = new PdfArray(new float[] {
cropBox.Left, (cropBox.Bottom + cropBox.Top) / 2,
cropBox.Right, cropBox.Top });
PdfDictionary pageDictionary = pdfReader.GetPageN(i);
pageDictionary.Put(PdfName.CROPBOX, newCropBox);
pageDictionary.Put(PdfName.MEDIABOX, newCropBox);
}
}
(CutPages test CutInHalfForTmighty)
Before
After
I tiied to add a TextBox to the right corner of the existing pdf using c#, but im unable to get it done. I have wrote the following code,but it is not helping in solving the problem, can any body please suggest me
using (MemoryStream stream = new MemoryStream())
{
PdfReader reader = new PdfReader(bytes);
PdfReader.unethicalreading = true;
Paragraph p = new Paragraph();
Document doc = new Document();
using (PdfStamper stamper = new PdfStamper(reader, stream))
{
PdfContentByte canvas = stamper.GetOverContent(1);
iTextSharp.text.Rectangle size = reader.GetPageSizeWithRotation(1);
//PdfContentByte cb = null;
//PdfImportedPage page;
int pages = reader.NumberOfPages;
for (int i = 1; i <= pages; i++)
{
var size1 = reader.GetPageSize(i);
w = size1.Width;
h = size1.Height;
stamper.FormFlattening = true;
TextField tf = new TextField(stamper.Writer, new iTextSharp.text.Rectangle(0, 0, 300, 100), displaytext);
//Change the orientation of the text
tf.Rotation = 0;
stamper.AddAnnotation(tf.GetTextField(), i);
}
}
bytes = stream.ToArray();
}
File.WriteAllBytes(str, bytes);
As the OP clarified in comments to the question, he wants
to add the text as a page content in the right bottom corner of the page and
the page content previously existing there to be removed.
A simple implementation of this would include
first covering the existing page content with a filled rectangle and
then writing text there.
These tasks can be achieved with these helper methods:
void EmptyTextBoxSimple(PdfStamper stamper, int pageNumber, Rectangle boxArea, BaseColor fillColor)
{
PdfContentByte canvas = stamper.GetOverContent(pageNumber);
canvas.SaveState();
canvas.SetColorFill(fillColor);
canvas.Rectangle(boxArea.Left, boxArea.Bottom, boxArea.Width, boxArea.Height);
canvas.Fill();
canvas.RestoreState();
}
and
ColumnText GenerateTextBox(PdfStamper stamper, int pageNumber, Rectangle boxArea)
{
PdfContentByte canvas = stamper.GetOverContent(pageNumber);
ColumnText columnText = new ColumnText(canvas);
columnText.SetSimpleColumn(boxArea);
return columnText;
}
E.g. like this:
using (PdfReader reader = new PdfReader(source))
using (PdfStamper stamper = new PdfStamper(reader, new FileStream(dest, FileMode.Create)))
{
Rectangle cropBox = reader.GetCropBox(1);
Rectangle bottomRight = new Rectangle(cropBox.GetRight(216), cropBox.Bottom, cropBox.Right, cropBox.GetBottom(146));
EmptyTextBoxSimple(stamper, 1, bottomRight, BaseColor.WHITE);
ColumnText columnText = GenerateTextBox(stamper, 1, bottomRight);
columnText.AddText(new Phrase("Some test text to draw into a text box in the lower right corner of the first page"));
columnText.Go();
}
For this source page
the sample code generates this
Addendum
In a comment the OP indicated
it is working for all files but for some pdf files it is displaying in the middle
Eventually he supplied a sample file for which the issue occurs. And indeed, with this file the issue could be reproduced.
The cause for the issue is that the pages in the sample file use page rotation, something that iText (only) partially allows users to ignore. In particular iText automatically rotates text to be upright after rotation and transforms coordinates, but when retrieving the cropbox of a page, one still has to apply rotation before making use of it coordinates. Thus, a more complete example would be like this:
using (PdfReader reader = new PdfReader(source))
using (PdfStamper stamper = new PdfStamper(reader, new FileStream(dest, FileMode.Create)))
{
Rectangle cropBox = reader.GetCropBox(1);
int rotation = reader.GetPageRotation(1);
while (rotation > 0)
{
cropBox = cropBox.Rotate();
rotation -= 90;
}
Rectangle bottomRight = new Rectangle(cropBox.GetRight(216), cropBox.Bottom, cropBox.Right, cropBox.GetBottom(146));
EmptyTextBoxSimple(stamper, 1, bottomRight, BaseColor.WHITE);
ColumnText columnText = GenerateTextBox(stamper, 1, bottomRight);
columnText.AddText(new Phrase("Some test text to draw into a text box in the lower right corner of the first page"));
columnText.Go();
}
I'm trying to place text into a ColumnText object and calculate its exact height. I'm using iTextSharp 5.5.9
What I'm finding is that there appears to be some "padding" at the top of the ColumnText object and it causes the height calculation to be flawed and the text to be misplaced. I'm trying to understand exactly what's happening - here's my code:
var doc = new Document(PageSize.LETTER, DocumentRenderer.PageMarginSize, DocumentRenderer.PageMarginSize, DocumentRenderer.PageTopMarginSize, DocumentRenderer.PageMarginSize);
doc.SetPageSize(PageSize.LETTER.Rotate());
var writer = PdfWriter.GetInstance(doc, fs);
doc.Open();
var x = 5;
var y = doc.PageSize.Height - 5;
var width = doc.PageSize.Width/ 2;
var height = doc.PageSize.Height - 10;
var lines = new List<string> { "Test string", };// "Test string 2", "Test string 3", "Test string 4" };
for (int i = 0; i < 6; i++)
{
lines.Add("Test String " + i);
}
lines.Add(lines.Aggregate((a, b) => a + ", " + b));
lines.Add(lines.Aggregate((a, b) => a + "\n" + b));
PdfContentByte cb = writer.DirectContent;
cb.SetTextRenderingMode(PdfContentByte.TEXT_RENDER_MODE_FILL);
cb.SetCMYKColorFill(DocumentRenderer.DarkColor.C, DocumentRenderer.DarkColor.M, DocumentRenderer.DarkColor.Y, DocumentRenderer.DarkColor.K);
Font ListFont = new Font(DocumentRenderer.TextFont, 12);
ColumnText ct = new ColumnText(cb);
ct.Leading = 14;
//ct.UseAscender = true;
ct.Alignment = Element.ALIGN_LEFT;
ct.SetSimpleColumn(x, y - height, x + width, y);
lines.ForEach(line =>
{
ct.AddText(new Phrase(line + "\n", ListFont));
});
ct.Go();
var height1 = (ct.LinesWritten * ct.Leading);
var height2 = y - ct.YLine;
DocumentRenderer.DrawBox(ref doc, ref writer, new BoxInfo(x, y, width, height2), DocumentRenderer.HighlightColor);
if (doc.IsOpen())
doc.Close();
Here are the results - please note that I highlighted the text with my cursor for effect.
I stumbled into this post (iText placement of Phrase within ColumnText) regarding UseAscender and tried it out by uncommenting that line in the code. You can see that on the right in the picture and it didn't appear to work like I was hoping.
What I really want is the text to still have its leading drawn correctly but for that to start at the top of the ColumnText. Also, I'm trying to get an accurate height for the text. The ct.YLine appears to give me the line at the bottom of the text but the text will overhang below that slightly. I'm not sure why that's not correct but I need to know the exact height if that's possible...
Anyone know how I might achieve these two things?
I cannot get the text to be centered on the page. What am I doing wrong? I have tried several ways to get the page with, but none seem to make the text centered on the page.....
BaseFont bf = BaseFont.CreateFont("c:\\windows\\fonts\\calibri.ttf", BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
PdfReader reader = new PdfReader("C:\\temp\\Certificate12.pdf");
var pageSize = reader.GetPageSize(1);
iTextSharp.text.Rectangle rec2 = new iTextSharp.text.Rectangle(PageSize.LETTER);
PdfStamper stamper = new PdfStamper(reader, stream1);
PdfContentByte canvas = stamper.GetUnderContent(1);
canvas.BeginText();
canvas.SetFontAndSize(bf, 24);
string nameText = "First Name Last Name";
int textWidth = (int)nameText.Length;
int canvasWidth = (int)canvas.PdfDocument.PageSize.Width;
float xStart = (canvasWidth / 2) - (textWidth / 2);
canvas.ShowTextAligned(PdfContentByte.ALIGN_CENTER, nameText, xStart, pageSize.GetTop(Utilities.MillimetersToPoints(145)), 0);
First of all, if you use ShowTextAligned with ALIGN_CENTER, iTextSharp will center the text for you, so you do not have to deal with the text width at all. You merely need to tell it to center the text on which center point.
Thus, you can center your text on the page like this:
BaseFont bf = BaseFont.CreateFont("c:\\windows\\fonts\\calibri.ttf", BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
using (PdfReader reader = new PdfReader(source))
using (PdfStamper stamper = new PdfStamper(reader, new FileStream(dest, FileMode.Create, FileAccess.Write)))
{
Rectangle pageSize = reader.GetPageSize(1);
PdfContentByte canvas = stamper.GetUnderContent(1);
string nameText = "First Name Last Name";
canvas.BeginText();
canvas.SetFontAndSize(bf, 24);
canvas.ShowTextAligned(PdfContentByte.ALIGN_CENTER, nameText, (pageSize.Left + pageSize.Right) / 2, pageSize.GetTop(Utilities.MillimetersToPoints(145)), 0);
canvas.EndText();
}
I am using itextpdf-5.5.6 for publish my data.
I'm trying to set page numbers in PdfPCell of my pdf using following format : page_num/total_page_num
For this I use PdfTemplate object filling inside total page number before close document.
It warks, but PdfTemplate exceeds PdfPCell border.
Is it possible that all content of cell stay inside of cell properly ?
PdfTemplate pageNumTemplate;
#Test
public void quick_test() throws FileNotFoundException, DocumentException {
String filename = "C:\\test.pdf";
File file = new File(filename);
Document document = new Document();
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(filename));
PageNumberEvent pageNumberEvent = new PageNumberEvent();
writer.setPageEvent(pageNumberEvent);
document.open();
for(int i = 0; i < 10000; i++){
document.add(new Paragraph("This is my paragraph"));
document.newPage();
}
document.close();
}
public class PageNumberEvent extends PdfPageEventHelper {
#Override
public void onEndPage(PdfWriter writer, Document document) {
if(pageNumTemplate == null){
pageNumTemplate = writer.getDirectContent().createTemplate(0.1f, 0.1f);
}
PdfPTable table = new PdfPTable(1);
table.setSpacingBefore(50);
Paragraph para = new Paragraph();
Chunk pageNum = new Chunk(writer.getPageNumber() + "/");
para.add(pageNum);
Image totalPageNumImg = null;
try {
totalPageNumImg = Image.getInstance(pageNumTemplate);
} catch (BadElementException e) {
e.printStackTrace();
}
Chunk totalPageNumImgChunk = new Chunk(totalPageNumImg, 0, -1, true);
para.add(totalPageNumImgChunk);
para.setIndentationLeft(370);
PdfPCell cell = new PdfPCell(para);
cell.addElement(para);
table.addCell(cell);
try {
document.add(table);
} catch (DocumentException e) {
e.printStackTrace();
}
}
#Override
public void onCloseDocument(PdfWriter writer,Document document) {
String totalPageNumString = String.valueOf(writer.getPageNumber() - 1);
float widthPoint = totalPageNumString.length() * 10;
float heightPoint = totalPageNumString.length() * 20;
Phrase totalPageNumPhrase = new Phrase(totalPageNumString);
Rectangle templRect = pageNumTemplate.getBoundingBox();
Rectangle rectangle = new Rectangle(templRect.getLeft(), templRect.getBottom(), widthPoint, heightPoint + 2);
pageNumTemplate.setBoundingBox(rectangle);
ColumnText.showTextAligned(pageNumTemplate, Element.ALIGN_LEFT, totalPageNumPhrase, 0, 1, 0);
}
}
Early, in the first onEndPage call, you create a minute template (0.1x0.1) to start with
pageNumTemplate = writer.getDirectContent().createTemplate(0.1f, 0.1f);
which fits into your cell. At the end though, in onCloseDocument, after everything has been layout'ed to a fixed position, you resize this template which makes it grow to the left:
Rectangle templRect = pageNumTemplate.getBoundingBox();
Rectangle rectangle = new Rectangle(templRect.getLeft(), templRect.getBottom(), widthPoint, heightPoint + 2);
pageNumTemplate.setBoundingBox(rectangle);
If you want your template to remain in your table cell, you have to initialize it with a width which most likely will be enough to hold the number of pages, e.g.
pageNumTemplate = writer.getDirectContent().createTemplate(30f, 0.1f);
Here you may have to play around a bit...
As the OP indicated in a comment, not only keeping all content of cell stay inside of cell is required but the content also is expected to be right aligned in the cell.
This second requirement obviously cannot be fulfilled by the OP's code which draws the number of pages into the template using ALIGN_LEFT. Furthermore it does not mix and match with resizing the template on the right size because it has already been positioned on the pages.
To fulfill it, therefore, the OP should
horizontally initialize the template with a size large enough for any expected number of pages (onEndPage);
fill the table cell with right alignment (instead of some pseudo right alignment by means of setIndentationLeft) (onEndPage);
leave the horizontal size of the template as is (onCloseDocument); and
show the number of pages right aligned to the right template border (onCloseDocument).