I am trying to set custom font to Paragraph, but I can't make it work.
I tried setting .Font= , but it only works size-wise, but it ignores font. Could you please assist?
Paragraph T = new Paragraph(newTempLine);
iTextSharp.text.Font contentFont = iTextSharp.text.FontFactory.GetFont("Webdings", 12, iTextSharp.text.Font.NORMAL);
T.Font = contentFont;
myDocument.Add(T);
Set it in the constructor:
Font contentFont = FontFactory.GetFont(…);
Paragraph para = new Paragraph(newTempLine, contentFont);
Check if below works:
string name = "Century Gothic Bold";
if (!FontFactory.IsRegistered(name))
{
string systemRoot = Environment.GetEnvironmentVariable("SystemRoot");
string path = Path.Combine(systemRoot, "fonts", #"GOTHICB.TTF");
FontFactory.Register(path);
}
var font = FontFactory.GetFont(name, fontSize, textColor);
var paragraph = new Paragraph(text, font);
Phrase phrase = new Phrase(paragraph);
var myPdfCell = new PdfPCell(phrase);
Related
I want to create a PDF file with Arabic text content in C#. I'm using iTextSharp to create this. I followed the instruction in http://geekswithblogs.net/JaydPage/archive/2011/11/02/using-itextsharp-to-correctly-display-hebrew--arabic-text-right.aspx. I want to insert the following Arabic sentence in pdf.
تم إبرام هذا العقد في هذا اليوم [●] م الموافق [●] من قبل وبين .
The [●] need to be replaced by dynamic English words. I tried to implement this by using ARIALUNI.TTF [This tutorial link suggested it]. The code is given below.
public void WriteDocument()
{
//Declare a itextSharp document
Document document = new Document(PageSize.A4);
//Create our file stream and bind the writer to the document and the stream
PdfWriter writer = PdfWriter.GetInstance(document, new FileStream(#"D:\Test.Pdf", FileMode.Create));
//Open the document for writing
document.Open();
//Add a new page
document.NewPage();
//Reference a Unicode font to be sure that the symbols are present.
BaseFont bfArialUniCode = BaseFont.CreateFont(#"D:\ARIALUNI.TTF", BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
//Create a font from the base font
Font font = new Font(bfArialUniCode, 12);
//Use a table so that we can set the text direction
PdfPTable table = new PdfPTable(1);
//Ensure that wrapping is on, otherwise Right to Left text will not display
table.DefaultCell.NoWrap = false;
//Create a regex expression to detect hebrew or arabic code points
const string regex_match_arabic_hebrew = #"[\u0600-\u06FF,\u0590-\u05FF]+";
if (Regex.IsMatch("م الموافق", regex_match_arabic_hebrew, RegexOptions.IgnoreCase))
{
table.RunDirection = PdfWriter.RUN_DIRECTION_RTL;
}
//Create a cell and add text to it
PdfPCell text = new PdfPCell(new Phrase(" : "+"من قبل وبين" + " 2007 " + "م الموافق" + " dsdsdsdsds " + "تم إبرام هذا العقد في هذا اليوم ", font));
//Ensure that wrapping is on, otherwise Right to Left text will not display
text.NoWrap = false;
//Add the cell to the table
table.AddCell(text);
//Add the table to the document
document.Add(table);
//Close the document
document.Close();
//Launch the document if you have a file association set for PDF's
Process AcrobatReader = new Process();
AcrobatReader.StartInfo.FileName = #"D:\Test.Pdf";
AcrobatReader.Start();
}
While calling this function, I got a PDF with some Unicode as given below.
اذه يف دقعلا اذه ماربإ مت dsdsdsdsds قفاوملا م 2007 نيبو لبق نم
مويلا
It is not matching with our hard coded Arabic sentence. Is this a issue of font? Please help me or suggest me any other method to implement the same.
#csharpcoder has the right idea, but his execution is off. He doesn't add the cell to a table, and the table doesn't end up in the document.
void Go()
{
Document doc = new Document(PageSize.LETTER);
string yourPath = "foo/bar/baz.pdf";
using (FileStream os = new FileStream(yourPath, FileMode.Create))
{
PdfWriter.GetInstance(doc, os); // you don't need the return value
doc.Open();
string fontLoc = #"c:\windows\fonts\arialuni.ttf"; // make sure to have the correct path to the font file
BaseFont bf = BaseFont.CreateFont(fontLoc, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
Font f = new Font(bf, 12);
PdfPTable table = new PdfPTable(1); // a table with 1 cell
Phrase text = new Phrase("العقد", f);
PdfPCell cell = new PdfPCell(text);
table.RunDirection = PdfWriter.RUN_DIRECTION_RTL; // can also be set on the cell
table.AddCell(cell);
doc.Add(table);
doc.Close();
}
}
You will probably want to get rid of the cell borders etc, but that information can be found elsewhere on SO or the iText website. iText should be able to handle text that contains both RTL and LTR characters.
EDIT
I think the source problem is actually with how the Arabic text is rendered in Visual Studio and in Firefox (my browser), or alternatively with how the Strings are concatenated. I'm not very familiar with Arabic text editors, but the text seems to come out correctly if we do this:
FYI I had to take a screenshot, because copy-pasting into the browser from VS (and vice versa) messes up the order of the parts of the text.
Right-to-left writing and Arabic ligatures are only supported in ColumnText and PdfPTable!
Try out the below code :
Document Doc = new Document(PageSize.LETTER);
//Create our file stream
using (FileStream fs = new FileStream(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Test.pdf"), FileMode.Create, FileAccess.Write, FileShare.Read))
{
//Bind PDF writer to document and stream
PdfWriter writer = PdfWriter.GetInstance(Doc, fs);
//Open document for writing
Doc.Open();
//Add a page
Doc.NewPage();
//Full path to the Unicode Arial file
string ARIALUNI_TFF = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Fonts), "arabtype.TTF");
//Create a base font object making sure to specify IDENTITY-H
BaseFont bf = BaseFont.CreateFont(ARIALUNI_TFF, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
Font f = new Font(bf, 12);
//Write some text, the last character is 0x0278 - LATIN SMALL LETTER PHI
Doc.Add(new Phrase("This is a ميسو ɸ", f));
//add Arabic text, for instance in a table
PdfPCell cell = new PdfPCell();
cell.AddElement(new Phrase("Hello\u0682", f));
cell.RunDirection = PdfWriter.RUN_DIRECTION_RTL;
//Close the PDF
Doc.Close();
}
I hope these notes can help you from other answers:
Use a safe code to achieve your font:
var tahomaFontFile = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.Fonts),
"Tahoma.ttf");
Use BaseFont.IDENTITY_H and BaseFont.EMBEDDED properties.
var tahomaBaseFont = BaseFont.CreateFont(tahomaFontFile,
BaseFont.IDENTITY_H,
BaseFont.EMBEDDED);
var tahomaFont = new Font(tahomaBaseFont, 8, Font.NORMAL);
Use PdfWriter.RUN_DIRECTION_RTL, for both your cell and your table:
var table = new PdfPTable(1)
{
RunDirection = PdfWriter.RUN_DIRECTION_RTL
};
var phrase = new Phrase("تم إبرام هذا العقد في هذا اليوم [●] م الموافق [●] من قبل وبين .",
tahomaFont);
var cell = new PdfPCell(phrase)
{
RunDirection = PdfWriter.RUN_DIRECTION_RTL,
Border = 0,
};
i believe your problem in string structure part, try to use the below code it works fine with me, Good Luck.`
public static void GeneratePDF()
{
//Declare a itextSharp document
Document document = new Document(PageSize.A4);
Random ran = new Random();
string PDFFileName = string.Format(#"C:\Test{0}.Pdf", ran);
//Create our file stream and bind the writer to the document and the stream
PdfWriter writer = PdfWriter.GetInstance(document, new FileStream(PDFFileName, FileMode.Create));
//Open the document for writing
document.Open();
//Add a new page
document.NewPage();
var ArialFontFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Fonts), "ARIALUNI.ttf");
//Reference a Unicode font to be sure that the symbols are present.
BaseFont bfArialUniCode = BaseFont.CreateFont(ArialFontFile, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
//Create a font from the base font
Font font = new Font(bfArialUniCode, 12);
//Use a table so that we can set the text direction
var table = new PdfPTable(1)
{
RunDirection = PdfWriter.RUN_DIRECTION_RTL,
};
//Ensure that wrapping is on, otherwise Right to Left text will not display
table.DefaultCell.NoWrap = false;
ContentObject CO = new ContentObject();
CO.Name = "Ahmed Gomaa";
CO.StartDate = DateTime.Now.AddMonths(-5);
CO.EndDate = DateTime.Now.AddMonths(43);
string content = string.Format(" تم إبرام هذا العقد في هذا اليوم من قبل {0} في تاريخ بين {1} و {2}", CO.Name, CO.StartDate, CO.EndDate);
var phrase = new Phrase(content, font);
//var phrase = new Phrase("الحمد لله رب العالمين", font);
//Create a cell and add text to it
PdfPCell text = new PdfPCell(phrase)
{
RunDirection = PdfWriter.RUN_DIRECTION_RTL,
Border = 0
};
//Ensure that wrapping is on, otherwise Right to Left text will not display
text.NoWrap = false;
//Add the cell to the table
table.AddCell(text);
//Add the table to the document
document.Add(table);
//Close the document
document.Close();
//Launch the document if you have a file association set for PDF's
Process AcrobatReader = new Process();
AcrobatReader.StartInfo.FileName = PDFFileName;
AcrobatReader.Start();
}
}
public class ContentObject
{
public string Name { set; get; }
public DateTime StartDate { set; get; }
public DateTime EndDate { set; get; }
}
`
I want to decorate various paragraphs in a PDF file by bolding some text, using different fonts, and colors. I thought I found the code for how to do that (below), but it's not working - all the text is the same font, color (black), and size. Why are my virtual sweat-inducing efforts to prettyify the PDF file so far in vain? Here is my code:
using (var ms = new MemoryStream())
{
using (var doc = new Document(PageSize.A4, 50, 50, 25, 25))
{
using (var writer = PdfWriter.GetInstance(doc, ms))
{
doc.Open();
// Mimic the appearance of Duckbill_Platypus.pdf
var docTitle = new Paragraph("Duckbilled Platypi - they're not what's for dinner");
var titleFont = FontFactory.GetFont("Courier", 18, BaseColor.BLACK);
docTitle.Font = titleFont;
doc.Add(docTitle);
var subTitle = new Paragraph("Baby, infant, toddler, and perhaps 'Terrible 2s' Platypi are called Platypups");
var subtitleFont = FontFactory.GetFont("Times Roman", 13, BaseColor.BLACK);
subTitle.Font = subtitleFont;
doc.Add(subTitle);
var importantNotice = new Paragraph("Teenage platypi are sometimes called Platydude[tte]s");
var importantNoticeFont = FontFactory.GetFont("Courier", 13, BaseColor.RED);
importantNotice.Font = importantNoticeFont;
doc.Add(importantNotice);
ListColumns lc;
for (int i = 0; i < listOfListItems.Count; i++)
{
lc = listOfListItems[i];
sb.AppendLine(String.Format(#"<p>Request date is {0}; Payee Name is {1}; Remit Address or Mail Stop is {2}; Last 4 of SSN or ITIN is {3}; 204 Submitted or on file is {4}; Requester Name is {5}; Dept or Div Name is {6}; Phone is {7}; Email is {8}</p>",
lc.li_requestDate, lc.li_payeeName, lc.li_remitAddressOrMailStop, lc.li_last4SSNDigitsOrITIN, lc.li_204SubmittedOrOnFile, lc.li_requesterName, lc.li_deptDivName, lc.li_phone, lc.li_email));
}
String htmlToRenderAsPDF = sb.ToString();
//XMLWorker also reads from a TextReader and not directly from a string
using (var srHtml = new StringReader(htmlToRenderAsPDF))
{
XMLWorkerHelper.GetInstance().ParseXHtml(writer, doc, srHtml);
}
doc.Close();
}
}
try
{
var bytes = ms.ToArray();
var testFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "iTextSharpTest.pdf");
File.WriteAllBytes(testFile, bytes);
}
catch (Exception ex)
{
String exMsg = ex.Message;
; // what is "ex" here?
}
I'm setting two sizes of font (18 and 13), two colors (black and red), two fonts ("Courier" and "Times Roman") yet all my hours of travail here for PDF fancification seem yet in vain (apologies to Vachel Lindsay and Abraham Lincoln).
You should use the font when creating the Paragraph:
Font f = new Font(FontFamily.COURIER);
Paragraph p = new Paragraph("text", f);
document.add(p);
Or you should wait to add content until you've set the font:
Paragraph p = new Paragraph();
Font f = new Font(FontFamily.COURIER);
p.setFont(f);
p.addText("text");
document.add(p);
In your code, you have something like this:
Paragraph p = new Paragraph("text");
Font f = new Font(FontFamily.COURIER);
p.setFont(f);
document.add(p);
When setting the font using setFont(), you set the font for the text that will be added to the paragraph, not to the text that is already stored in the paragraph.
For instance:
Paragraph p = new Paragraph("font 1 ");
p.setFont(new Font(FontFamily.COURIER);
p.add("font 2");
document.add(p);
This will add the text font 1 in the default font and font 2 in Courier.
So, I've seen an example for a newly created doc
Rectangle r = new Rectangle(400, 300);
Document doc = new Document(r);
try
{
PdfWriter.GetInstance(doc, new FileStream("C:/Blocks2.pdf", FileMode.Create));
doc.Open();
string text = #"The result can be seen below, which shows the text
having been written to the document but it looks a
mess. ";
text = text.Replace(Environment.NewLine, String.Empty).Replace(" ", String.Empty);
Font brown = new Font(Font.FontFamily.COURIER, 9f, Font.NORMAL, new BaseColor(163, 21, 21));
Font lightblue = new Font(Font.FontFamily.COURIER, 9f, Font.NORMAL, new BaseColor(43, 145, 175));
Font courier = new Font(Font.FontFamily.COURIER, 9f);
Font georgia = FontFactory.GetFont("georgia", 10f);
georgia.Color = BaseColor.GRAY;
Chunk beginning = new Chunk(text, georgia);
Phrase p1 = new Phrase(beginning);
Chunk c1 = new Chunk("You can of course force a newline using \"", georgia);
Chunk c2 = new Chunk(#"\n", brown);
Chunk c3 = new Chunk("\" or ", georgia);
Chunk c4 = new Chunk("Environment", lightblue);
Chunk c5 = new Chunk(".NewLine", courier);
Chunk c6 = new Chunk(", or even ", georgia);
Chunk c7 = new Chunk("Chunk", lightblue);
Chunk c8 = new Chunk(".NEWLINE", courier);
Chunk c9 = new Chunk(" as part of the string you give a chunk.", georgia);
Phrase p2 = new Phrase();
p2.Add(c1);
p2.Add(c2);
p2.Add(c3);
p2.Add(c4);
p2.Add(c5);
p2.Add(c6);
p2.Add(c7);
p2.Add(c8);
p2.Add(c9);
Paragraph p = new Paragraph();
p.Add(p1);
p.Add(p2);
p.Alignment = Element.ALIGN_JUSTIFIED;
doc.Add(p);
}
As you can see, the document is initiated with a rectangle Document doc = new Document(r);
So, the result of this code is gonna be like this
My question is: how do I append text, which will consider page size in an existing document?
Is it possible to add a rectangle with a text in a doc? Or maybe append a newly created document to an existing one?
I realise, that I should probably read iText books, but I'm kind of running out of time and this is the last thing I have to figure out. Is there a clean easy solution, to my question? Thank you
UPDATE:
Sadly, for some reason the solution by Alexis Pigeon doesn't work for me.
I've written
Document doc = new Document();
var writer = PdfWriter.GetInstance(doc, new FileStream("C:/Blocks2.pdf", FileMode.Open));
doc.Open();
and at the end
doc.Add(p); doc.Close()
And no changes are applied to the file, although code runs smoothly.
Something tells me, that this approach is wrong, since I haven't met any code examples, where people would have used Document with and existing pdf file, only creating a new one. Usually it's PDFStamper or PDFWriter.
So, let me rephrase my question: How do I append text to an existing document so that it will fill certain rectangle?
So, after looking around I figured out, that what Im looking for is called "hyphenation". Didnt know this word.
To fit the text in a rectangle area you need to create a table with one cell and invisible borders. I've also encoutered issues with encoding. Here is the code.:
PdfReader pdf = new PdfReader("Test1.pdf");
File.Delete("C:/Blocks.pdf");
PdfStamper stp = new PdfStamper(pdf, new FileStream("C:/Blocks.pdf", FileMode.OpenOrCreate));
var canvas = stp.GetOverContent(1);
PdfPTable table = new PdfPTable(1);
table.SetTotalWidth(new float[] { 100 });
Phrase phrase = new Phrase();
phrase.Hyphenation = new HyphenationAuto("ru", "RU", 2, 2);
var bf = BaseFont.CreateFont("c:/windows/fonts/arialbd.ttf", "Cp1251", BaseFont.EMBEDDED);
phrase.Add(new Chunk("О БОЖЕ ТЫ МОЙ НЕУЖЕЛИ РАБОТАЕТ ЕСЛИ РАБОТАЕТ Я БЫЛ БЫ ТАК СЧАСТЛИВ", new Font(bf, 12)));
PdfPCell cell = new PdfPCell(phrase);
cell.Border = Rectangle.NO_BORDER;
table.AddCell(cell);
table.WriteSelectedRows(0, 1, 200, 200, canvas);
stp.Close();
I use Image from Resources to LegendItem in WinForms
var ImageName = "ImageName";
myChart.Images.Add(new NamedImage(ImageName, Resources.Image));
LegendItem legendItem = new LegendItem();
legendItem.Name = "legend text";
legendItem.Image = ImageName;
myChart.Legends[Legend.Name].CustomItems.Add(legendItem);
But the size of Image is too small.
How can I change it?
You should use custom LegendCell in this case. This means you define the cells for your LegendItem specifying their properties. Something like this:
LegendItem legendItem = new LegendItem();
LegendCell cell1 = new LegendCell();
cell1.Name = "cell1";
cell1.Text = "legend text";
// here you can specify alignment, color, ..., too
LegendCell cell2 = new LegendCell();
cell2.Name = "cell2";
cell2.CellType = System.Windows.Forms.DataVisualization.Charting.LegendCellType.Image;
cell2.Image = "path of your img";
cell2.Size = new Size(.....);
legendItem.Cells.Add(cell1);
legendItem.Cells.Add(cell2);
Im tasked to use OPEN XML SDK 2.0 and had encountered this problem. Is it possible to have different styles for a single CellValue inside a cell something like the picture below:
A: The plain text
B: Bold and Underlined
NOTE: I need both in a single cell only thanks :)
Yes that is possible. One way is to format the value that will be inserted into the SharedStringTable. This snippet will create your example above:
// Creates an SharedStringItem instance and adds its children.
public SharedStringItem GenerateSharedStringItem()
{
SharedStringItem sharedStringItem1 = new SharedStringItem();
Run run1 = new Run();
RunProperties runProperties1 = new RunProperties();
Bold bold1 = new Bold();
Underline underline1 = new Underline();
FontSize fontSize1 = new FontSize(){ Val = 11D };
Color color1 = new Color(){ Theme = (UInt32Value)1U };
RunFont runFont1 = new RunFont(){ Val = "Calibri" };
FontFamily fontFamily1 = new FontFamily(){ Val = 2 };
FontScheme fontScheme1 = new FontScheme(){ Val = FontSchemeValues.Minor };
runProperties1.Append(bold1);
runProperties1.Append(underline1);
runProperties1.Append(fontSize1);
runProperties1.Append(color1);
runProperties1.Append(runFont1);
runProperties1.Append(fontFamily1);
runProperties1.Append(fontScheme1);
Text text1 = new Text();
text1.Text = "Project Name:";
run1.Append(runProperties1);
run1.Append(text1);
Run run2 = new Run();
RunProperties runProperties2 = new RunProperties();
FontSize fontSize2 = new FontSize(){ Val = 11D };
Color color2 = new Color(){ Theme = (UInt32Value)1U };
RunFont runFont2 = new RunFont(){ Val = "Calibri" };
FontFamily fontFamily2 = new FontFamily(){ Val = 2 };
FontScheme fontScheme2 = new FontScheme(){ Val = FontSchemeValues.Minor };
runProperties2.Append(fontSize2);
runProperties2.Append(color2);
runProperties2.Append(runFont2);
runProperties2.Append(fontFamily2);
runProperties2.Append(fontScheme2);
Text text2 = new Text(){ Space = SpaceProcessingModeValues.Preserve };
text2.Text = " ALLAN";
run2.Append(runProperties2);
run2.Append(text2);
sharedStringItem1.Append(run1);
sharedStringItem1.Append(run2);
return sharedStringItem1;
}
You can insert that into the SharedStringTable and then set the cell value to be the index in the SharedStringTable where this was inserted.
There might be some other references that I forgot to include that might be defined in the StylesPart. I recommend creating this example in a blank Excel document and then using the Open XML Productivity Tool to look at the XML. The tool will also supply you with the code I provided you above. It should give you a general direction on where to go next.