I am using iTextSharp for PDF generating in Unity3d.
EDIT
Here is the code, but I am getting an empty PDF document:
void createPDF()
{
Document doc = new Document(iTextSharp.text.PageSize.A1, 5, 5, 5, 5);
PdfWriter wri = PdfWriter.GetInstance(doc, new FileStream("TestPDF.pdf", FileMode.Create));
doc.Open();
string fontPath = "C:\\windows\\Fonts\\arialuni.ttf";
BaseFont basefont = BaseFont.CreateFont(fontPath, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
iTextSharp.text.Font tahomaFont = new iTextSharp.text.Font(basefont, 10, iTextSharp.text.Font.NORMAL, BaseColor.RED);
PdfContentByte cb = wri.DirectContent;
ColumnText ct = new ColumnText(cb);
Phrase myText = new Phrase(GameObject.Find("TextPlay").GetComponent<TextMesh>().text);
ct.SetSimpleColumn(myText, 34, 750, 580, 317, 15, Element.ALIGN_LEFT);
ct.Go();
doc.Close();
}
The error message tells you that the font ArialJezici.ttf can't be used with encoding Identity_H, hence you will have to replace that font with another one, for instance with ArialUni.ttf.
Actually, this should work:
BaseFont bf = iTextSharp.text.pdf.BaseFont.CreateFont("C:\\WINDOWS\\Fonts\\ARIALUNI.TTF", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
Note that you need to provide the correct path. I don't think you're doing that in your example.
If the above snippet doesn't work, see itextsharp ARIALUNI.TTF copy on hosting server for an alternative example on how to do this.
Note that Arabic ligatures only work in the context of PdfPCell and ColumnText objects, they do not work in a Paragraph added to the Document because you can not set the run direction of a Paragraph. You can only set the run direction of a cell or a column.
If you do not set your run direction, the Arabic text will be written from left to right and no ligatures will be made, resulting in something this is not correct Arabic.
Contrary to the rules on StackOverflow, the original question was changed, resulting in my answer no longer being the answer to the new version of the question. This is an update with the anser to the current question:
With the BaseFont created in the first part of my answer, create a Font:
Font font = new Font(bf, 20);
Now create a ColumnText object and provide coordinates that fit your page:
ColumnText column = new ColumnText(writer.DirectContent);
column.SetSimpleColumn(36, 730, 569, 36);
If these coordinates do not fit your page, your content will be added to the file, but you won't see anything because the content is outside the visible area of the page.
For Arabic text, it is important that you set the run direction (I don't see you doing that anywhere):
column.RunDirection = PdfWriter.RUN_DIRECTION_RTL;
Now add the content:
column.AddElement(new Paragraph(GameObject.Find("TextPlay").GetComponent<TextMesh>().text));
column.Go();
This works for me, see the Java example or corresponding C# example, resulting in this file: ligatures_2.pdf
That file shows the Arabic text "لورانس العرب" three times. The first time, the characters are not in the right order. The second time, the characters are in the right order, but no ligatures are being made. The third time, it is shown correctly.
Related
I've been using itextsharp to generate pdf from my database data. My database data contains the text, the x and y coordinate and the page number. Here's how I do it.
string oldFile = Server.MapPath(string.Format("~/App_Data/Documents/Templates/{0}", documentModel.Filename));
// open the reader
PdfReader reader = new PdfReader(oldFile);
Rectangle size = reader.GetPageSizeWithRotation(1);
iTextSharp.text.Document document = new iTextSharp.text.Document(size);
PdfWriter writer = PdfWriter.GetInstance(document, _memoryStream);
writer.CloseStream = false;
document.Open();
PdfContentByte cb;
PdfImportedPage page;
BaseFont bf;
foreach (var pageNumber in pages)
{
document.NewPage();
cb = writer.DirectContent;
// create the new page and add it to the pdf
page = writer.GetImportedPage(reader, pageNumber);
cb.AddTemplate(page, 0, 0);
bf = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
cb.SetColorFill(BaseColor.DARK_GRAY);
cb.SetFontAndSize(bf, 9);
var items = documentModel.FieldContents.Where(a => a.Page == pageNumber).ToList();
foreach (var item in items)
{
cb.BeginText();
cb.ShowTextAligned(item.Alignment, item.Text ?? string.Empty, item.X, item.Y, item.Rotation);
cb.EndText();
}
}
////////////////////////////////////////////////////////////////////
document.Close();
writer.Close();
reader.Close();
byte[] byteInfo = _memoryStream.ToArray();
_memoryStream.Write(byteInfo, 0, byteInfo.Length);
_memoryStream.Position = 0;
RedirectToAction("Index");
return new FileStreamResult(_memoryStream, "application/pdf");
I've been using this for a while now. But I want to support chinese characters also. I tried inputting chinese characters, but it is not being displayed. I changed it back to english characters and it works. Any ideas? Thanks!
There are different errors in your code.
As mkl already explained, the Type 1 Helvetica font you're using isn't embedded and doesn't know anything about Chinese glyphs. You need to use a font that knows how to draw Chinese characters. Furthermore CP1252 is the encoding for the Latin alphabet, so you shouldn't expect it to know anything about Chinese.
You're also creating code that is illegal (and that results in invalid PDF syntax):
cb.BeginText();
cb.ShowTextAligned(...);
cb.EndText();
This is a text object for which no font and size is defined. You are using the ´setFontAndSize()´ method in graphics state (where it doesn't belong) instead of in text state (where it's required). The fact that this code runs, tells me that you're using an old iTextSharp version. You should upgrade.
The solution to your problem is to find examples about adding Chinese text with iText. Then create a ´Phrase´ and position it using ColumnText.showTextAligned();. By using ColumnText, you avoid the problem you now experience with the low-level approach: you're using beginText() and endText() without reading the PDF specification. ColumnText will do all this difficult work under the hood.
In case the Java examples confuse you, please visit this page where you'll find links to the C# port of the corresponding examples.
You can load you local Chinese font like this
BaseFont baseFont = BaseFont.CreateFont(
"C:\\Windows\\Fonts\\simhei.ttf",
BaseFont.IDENTITY_H,
BaseFont.EMBEDDED);
Font font = new Font(baseFont);
And then use the "font" for further texting. And you can reference the common used Chinese local fonts as below
{"yahei", "C:\\WINDOWS\\FONTS\\msyh.ttf"},
{"fangsong", "C:\\WINDOWS\\FONTS\\simfang.ttf"},
{"heiti" ,"C:\\Windows\\Fonts\\simhei.ttf"},
{"kaiti" ,"C:\\Windows\\Fonts\\simkai.ttf"},
{"lishu" ,"C:\\Windows\\Fonts\\SIMLI.TTF"},
{"youyuan" ,"C:\\Windows\\Fonts\\SIMYOU.TTF"},
{"songti" ,"C:\\Windows\\Fonts\\simsun.ttc,0"},
{"xinsongti" ,"C:\\Windows\\Fonts\\simsun.ttc,1"}
Hope it helps you!
I want to add Annotations comment in existing PDF file using iTextSharp with C#.
Please give sample code to add Annotations in existing PDF file.
Here PS Script for my Annotation:
[/Contents (My Text contents) /Rect [100 600 150 550] /SrcPg 1 /Title (My Title text) /Color [0 0 1] /Subtype /Caret /ANN pdfmark
The iText(Sharp) example TimetableAnnotations1.java / TimetableAnnotations1.cs from chapter 7 of iText in Action — 2nd Edition shows how to add annotations to existing PDFs in general.
The central code is (in the C# example):
rect = GetPosition(screening);
annotation = PdfAnnotation.CreateText(
stamper.Writer, rect, movie.MovieTitle,
string.Format(INFO, movie.Year, movie.Duration),
false, "Help"
);
annotation.Color = WebColors.GetRGBColor(
"#" + movie.entry.category.color
);
stamper.AddAnnotation(annotation, page);
where stamper is a PdfStamper working on your PDF file; movie is a data structure the example retrieves title, text and color of the annotation from.
PdfAnnotation offers multiple other Create... methods to create other types of annotations.
rect = GetPosition(screening);
can someone plz explain why is this is used..is there any way to find the current cursor position (top,bottom,height,width)
as with the annotation,
Document doc = new Document(PageSize.A4, 50, 50, 50, 50);
PdfWriter writer = PdfWriter.GetInstance(doc, new FileStream(#"C:\Users\Asus\Desktop\Test.pdf", FileMode.OpenOrCreate));
doc.AddDocListener(writer);
doc.Open();
doc.Add(new Annotation("annotation", "The text displayed in the sticky note", 100f, 500f, 200f, 600f));
doc.Close();
this works fine to me..
I want to put a check mark using zapfdingbatslist on my pdf document in iTextSharp in a specific location.
What I could do so far is I could show the check mark but it's all on the side of the document and not on a specific X, Y coordinate that I want it to be. I have a code below that would hopefully give you the idea of what I am talking about.
String outputFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Test.pdf");
System.IO.FileStream fs;
Document doc = new Document(PageSize.A4, 20, 20, 10, 10);
PdfContentByte cb;
PdfWriter writer;
fs = new System.IO.FileStream(outputFile, System.IO.FileMode.Create);
writer = PdfWriter.GetInstance(doc, fs);
doc.SetPageSize(iTextSharp.text.PageSize.A4.Rotate());
writer.AddViewerPreference(PdfName.PICKTRAYBYPDFSIZE, PdfBoolean.PDFTRUE);
doc.Open();
cb = writer.DirectContent;
List myList = new ZapfDingbatsList(52); // Check mark symbol from Dingbatslist
// I have some more code here but it is not needed for the problem
// and thererfore not shown
// I could shohw the dingbatslist check mark here
myList.Add(" ");
doc.Add(myList); // However I want to show it in a specific X, Y position
doc.Close();
writer.Close();
fs.Close();
Any idea?
Incidentally, I'm the author of most of the iText documentation (as well as the original developer of iText, including the Document, PdfWriter, ZapfdingbatsList,... classes), and I'd appreciate it if you took some time to read the iText documentation.
Let's start with chapter 2 and take a look at some C# examples that introduce the Font class.
For instance:
Font font = new Font(Font.FontFamily.ZAPFDINGBATS, 12);
Once you have a Font object, you can create a Phrase (also explained in chapter 2):
Phrase phrase = new Phrase(zapfstring, font);
Where zapfstring is a string containing any Zapfdingbats character you want.
To add this Phrase at an absolute position, you need to read chapter 3. Take a look at the examples for inspiration, for instance FoobarFilmfestival.cs:
PdfContentByte canvas = writer.DirectContent;
ColumnText.ShowTextAligned(canvas, Element.ALIGN_CENTER, phrase, 200, 500, 0);
Where 200 and 500 are an X and Y coordinate and 0 is an angle expressed in degrees. Instead of ALIGN_CENTER, you can also choose ALIGN_RIGHT or ALIGN_LEFT.
In your code sample you were adding a Zapfdingbats glyph to a document using a list. Please take a moment to put yourself in my place. Doesn't that feel as if you're the inventor of the sock attending a Red Hot Chili Peppers' concert?
I'm very new to using iTextSharp to generate a pdf. I have the following code that places text from my form to the pdf output. I am using a Phrase & ColumnText to position the text from a particular textbox onto my pdf output. I've tied a variable as well as the text property of the textbox as the Phrase string, but it places two sets of the same text on top of each other(screenshot).
string oldFile = Path.GetTempPath() + "invoice.pdf";
string newFile = Path.GetTempPath() + "NewInvoice.pdf";
PdfReader reader = new PdfReader(oldFile);
iTextSharp.text.Rectangle size = reader.GetPageSize(1);
Document doc = new Document(size);
FileStream fs = new FileStream(newFile, FileMode.Create, FileAccess.Write, FileShare.ReadWrite);
PdfWriter writer = PdfWriter.GetInstance(doc, fs);
doc.Open();
PdfContentByte cb = writer.DirectContent;
BaseFont bf = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1252, true);
cb.SetColorFill(BaseColor.BLACK);
cb.SetFontAndSize(bf, 12);
cb.BeginText();
cb.ShowTextAligned(PdfContentByte.ALIGN_LEFT, invoiceDate, 480, 603, 0);
cb.EndText();
PdfImportedPage page = writer.GetImportedPage(reader, 1);
cb.AddTemplate(page, 0, 0);
ColumnText ct = new ColumnText(cb);
Phrase phrase = new Phrase(textBox1.Text);
ct.SetSimpleColumn(phrase, 65, 375, 540, 300, 16, Element.ALIGN_LEFT);
ct.Go();
doc.Close();
fs.Close();
writer.Close();
reader.Close();
Process.Start(newFile);
If I assign a string (string whatever = "some text here...";) and place this in the Phrase string(..new Phrase(whatever); it works fine.
Let me start by saying that I'm the original developer of iText.
I hope you'll believe me when I say you should use a PdfReader/PdfStamper combination instead of a Document/PdfWriter combination. This is documented in chapter 6 of my book. You may not see any difference on the outside, but the PDF feel be so much better on the inside.
It's kind of strange that you're adding text at absolute positions. Wouldn't it be better to use a template that has some AcroForm fields on the locations where text is needed? Your code will be so much easier to maintain.
I also see that you're using HELVETICA as font with the parameter for embedding equal to true. Surely you know that the embedded parameter will be ignored for HELVETICA which is one of the Standard Type 1 fonts.
Finally for your question: I don't think your code is adding the phrase twice. I think you've been experimenting and that you're adding a new phrase over a phrase that already exists in the original file "invoice.pdf". If you're 100% that this isn't the case, then you should share your PDF so that I (or somebody else at iText) can inspect it.
I'm using iTextSharp 5.0.5 to create dynamic PDFs (asp.net c#), and I'm having problems with an extra space being inserted when creating a new page. The first page looks fine but on any additional pages the extra space appears at the top.
I've made a mini example that inserts a new page with a logo and a title for each article in a list. If I only insert the logo or only the title it works fine, but if I try to insert both there's an extra space coming from somewhere. Anyone got any ideas of what I'm doing wrong?
public static void CreatePDF(List<Item> Articles)
{
Document document = new Document(PageSize.A4, 35, 35, 35, 35);
MemoryStream memoryStream = new MemoryStream();
PdfWriter writer = PdfWriter.GetInstance(document, memoryStream);
document.Open();
for (int i = 0; i < Articles.Count; i++)
{
if (i > 0)
{
document.NewPage();
}
Image logo = Image.GetInstance(#"C:\logo.gif");
document.Add(logo);
Paragraph title = new Paragraph("test title", new Font(Font.FontFamily.HELVETICA, 20, Font.NORMAL, CMYKColor.BLACK));
document.Add(title);
}
document.Close();
SendPDFResponse(memoryStream, "myfile.pdf");
}
Thanks,
Annelie
There's no extra space on the pages that follow page 1. The problem is that there's less space on page 1.
No, this is not a joke. The problem is caused by the "leading" (that is: the space between two lines). The initial value for the leading is 0. When you add content to a document, this value changes to a value different from 0.
What is the leading you're using throughout the document? You should set this as the initial leading with the method setInitialLeading() in PdfWriter.
That sounds like a bug. I suspect some relatively new aspect of layout isn't being reset properly between pages.
Would you mind cross-posting this to the itext-questions mailing list?