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!
Related
I have a PDF File and I am trying to put a line in it using iTextSharp like this.
string Oldfile = #"C:\ThisTest.pdf";
string NewFile = #"C:\NewOne.pdf";
PdfReader reader = new PdfReader(Oldfile);
iTextSharp.text.Rectangle Size = reader.GetPageSizeWithRotation(1);
Document document = new Document(Size);
FileStream fs = new FileStream(NewFile, FileMode.Create, FileAccess.Write);
PdfWriter weiter = PdfWriter.GetInstance(document, fs);
document.Open();
PdfContentByte cb = weiter.DirectContent;
BaseFont bf = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.EMBEDDED);
cb.SetColorFill(BaseColor.DARK_GRAY);
cb.SetFontAndSize(bf, 8);
cb.BeginText();
string text = "Haseeb Ahmad";
cb.ShowTextAligned(1, text, 520, 640, 0);
cb.EndText();
PdfImportedPage page = weiter.GetImportedPage(reader, 1);
cb.AddTemplate(page, 0, 0);
document.Close();
fs.Close();
weiter.Close();
reader.Close();
I am trying to add a line to the end of this Document but after it does that code it creates the file and when I open it i cant see that text. When i do a search for that word it says its's there. Like this
That mean the code worked all the problem is the font can any one tell me how to make it come to the end of the page and show up instead of being hidden ?
Your code first draws the text
cb.SetColorFill(BaseColor.DARK_GRAY);
cb.SetFontAndSize(bf, 8);
cb.BeginText();
string text = "Haseeb Ahmad";
cb.ShowTextAligned(1, text, 520, 640, 0);
cb.EndText();
and thereafter copies the original page into this
PdfImportedPage page = weiter.GetImportedPage(reader, 1);
cb.AddTemplate(page, 0, 0);
Thus, your original page contents (which may include a white background fill) cover your new text.
Please change the order, copy the page first and then write the text.
If your task is indeed putting some text onto existing pages of an existing PDF, you should use other iText classes entirely: PdfStamper is made for just this kind of task while the PdfWriter is more made for creating new PDFs from scratch.
Your approach is quite lossy (it drops document level information and interactive parts like form fields) while PdfStamper keeps as much of the original PDF as possible.
I'm trying to build pdfs to digitize our reporting system at my company. I've used iTextSharp and so far it looks great but my margins don't seem to be working properly. I've set the margins to a config file and the left and right margins are working great, but my paragraph seems to start about 30% down the page regardless of the top and bottom margin. Here's the code I'm using:
public int PrintPdf()
{
//Getting the path
//Path.GetFileNameWithoutExtension("Test_Doc_Print") + ".pdf");
object OutputFileName = this._path;
//Making the PDF Doc
iTextSharp.text.Document PDFReport = new iTextSharp.text.Document
(
PageSize.A4.Rotate(),
/*this._left,
this._right,
this._top,
this._bottom*/
10,
10,
10,
10
);
//Setting The Font
string fontpath = #"C:\Windows\Fonts\";
BaseFont monoFont = BaseFont.CreateFont(fontpath + "Consola.ttf", BaseFont.CP1252, BaseFont.EMBEDDED);
Font fontPDF = new Font(monoFont, this._fontSize);
// create file stream for writing the PDF
FileStream fs = new FileStream(this._path, FileMode.Create, FileAccess.ReadWrite);
//FileStream fs = new FileStream(#"c:\\Reportlocation", FileMode.Create);
// Create an FCFC scan object to convert TextToPrint page at a time
FCFCScanner page = new FCFCScanner(this._text);
// Create PDF writer and associate with file stream
//iTextSharp.text.pdf.PdfWriter writer = new iTextSharp.text.pdf.PdfWriter.GetInstance(PDFReport, fs);
PdfWriter writer = PdfWriter.GetInstance(PDFReport, fs);
//Opening the PDF Doc
PDFReport.Open();
//Load each page from the string into the PDF
page.NextPage();
do
{
if (page.PageLength > 0)
{
Paragraph prg = new Paragraph(page.Page, fontPDF);
PDFReport.Add(prg);
PDFReport.NewPage();
page.NextPage();
}
} while (page.MorePages);
PDFReport.Close();
return (0);
}
I've set the margins to 10 (hardcoded for now) to show what I'm working with. This program should read a string that I send it from my StringBuider class.
It's designed to receive one page of text at a time and to convert it into a PDF document.
Ok, so the problem: when the page is built, the first paragraph doesn't begin at the top margin. If I reduce the margin, it doesn't shift the paragraph up to the new margin. It's causing my PDFs to be much longer as the text that fits easily on a printer page takes two PDF pages. Any help with getting my paragraph to simply begin at the top margin would be really appreciated.
I'm relatively new to programming and this is my first post, so if you need more information, let me know and I'll add more info.
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.
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.