I'm still a beginner in C# and I want to know is there an option of writing slavic letters č,ć,š,ž in PDF using iTextSharp. I was reading other posts about it but I can't apply their solution to my problem, maybe it's a bit to complicate to me as a beginner. This is my code:
SaveFileDialog pdfFile = new SaveFileDialog();
pdfFile.Filter = "PDF|*.pdf";
pdfFile.Title = "Spremi PDF";
pdfFile.FileName = "Ispit";
if (pdfFile.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
Document document = new Document(iTextSharp.text.PageSize.LETTER, 25, 25, 35, 35);
PdfWriter writer = PdfWriter.GetInstance(document, new FileStream(pdfFile.FileName, FileMode.Create));
document.Open();
foreach (List<string> question in questions)
{
document.NewPage();
foreach (string field in question)
{
document.Add(new Paragraph(field));
}
}
document.Close();
}
This code is maybe to simple and maybe there's a lots of better ways to do this but this is one of my first codes in C#.
I have solved my problem. This is the code that helped me:
BaseFont bf = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1250, false);
Font titleFont = new Font(bf,20);
Font infoFont = new Font(bf,16);
Thank you all
Related
Well, I am trying to export some data from my WinForms application to a PDF file. I have downloaded some fonts which support Turkish language characters. In the Turkish language, there are some letters like ç,ğ,ş,ö,ü,ı. My code has no problems with showing ç,ö,ü but somehow when the user inputs ğ, ş or ı, these letters get represented as blank in the PDF file.
My code is below:
Document doc= new Document(iTextSharp.text.PageSize.LETTER, 10, 10, 42, 35);
PdfWriter wri=PdfWriter.GetInstance(doc, new FileStream("Test.pdf", FileMode.Create));
doc.Open();
BaseFont bf = BaseFont.CreateFont(#"C:\aller.ttf", BaseFont.CP1252, BaseFont.EMBEDDED);
iTextSharp.text.Font font = new iTextSharp.text.Font(bf, 10, iTextSharp.text.Font.NORMAL);
Paragraph p1 = new Paragraph(new Chunk("çğşöüı", font));
doc.AddLanguage("tr-TR");
wri.SetLanguage("tr-TR");
doc.Add(p1);
doc.Close();
So, where is my mistake?
after tryings, I found the answer;
BaseFont bF = BaseFont.CreateFont("C:\\windows\\fonts\\arial.ttf", "windows-1254", true);
iTextSharp.text.Font f = new iTextSharp.text.Font(bF, 12f, iTextSharp.text.Font.NORMAL);
Chunk c = new Chunk();
c.Font = f;
iTextSharp.text.Document document = new iTextSharp.text.Document();
PdfWriter.GetInstance(document, new FileStream(#"C:\gorsel.pdf", FileMode.Create));
string text = "küçük harf türkçe karakterler : ç ğ ı ö ş ü \n" +
" BÜYÜK TÜRKÇE KARAKTERLER : Ç Ğ İ Ö Ş Ü";
c.Append(text);
document.Open();
document.Add(new Paragraph(c));
document.Close();
now I can use all special characters in my PDF file.
here is What i want i want to add page numbers to every pdf page that i generated on the fly.
i used on end page method but it did not worked out even when i added the doc bottom margin.
I decided to add the page numbers after the pdf is generated from the file path.
here is my code for generating pdf:
Document doc = new Document(iTextSharp.text.PageSize.LETTER, 10, 10, 42, 35);
PdfWriter wri = PdfWriter.GetInstance(doc, new FileStream("t5.pdf", FileMode.Create));
doc.Open();//Open Document to write
iTextSharp.text.Font font8 = FontFactory.GetFont("ARIAL", 7);
Paragraph paragraph = new Paragraph("Some content");
doc.Add(paragraph);
doc.Add(paragraph);// add paragraph to the document
doc.Close();
FileStream stream = File.OpenRead("t5.pdf");
byte[] fileBytes = new byte[stream.Length];
stream.Read(fileBytes, 0, fileBytes.Length);
stream.Close();
AddPageNumbers(fileBytes);
using (Stream file = File.OpenWrite("t5.pdf"))
{
file.Write(fileBytes, 0, fileBytes.Length);
}
}
and her is my add pagenumbers method:
MemoryStream ms = new MemoryStream();
PdfReader reader = new PdfReader(pdf);
int n = reader.NumberOfPages;
iTextSharp.text.Rectangle psize = reader.GetPageSize(1);
Document document = new Document(psize, 50, 50, 50, 50);
PdfWriter writer = PdfWriter.GetInstance(document, ms);
document.Open();
PdfContentByte cb = writer.DirectContent;
int p = 0;
for (int page = 1; page <= reader.NumberOfPages; page++)
{
document.NewPage();
p++;
PdfImportedPage importedPage = writer.GetImportedPage(reader, page);
cb.AddTemplate(importedPage, 0, 0);
BaseFont bf = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED);
cb.BeginText();
cb.SetFontAndSize(bf, 10);
cb.ShowTextAligned(PdfContentByte.ALIGN_CENTER, +p + "/" + n, 100, 450, 0);
cb.EndText();
}
document.Close();
return ms.ToArray();
how ever it does not add the page numbers to the pdf document so what is the alternatives here? what can i do.
When posting a question here, please only post the smallest amount of code possible. Your "create a sample PDF with multiple pages" is 116 lines long. Inside of it you've got complicated PdfPTable and DataTable logic that is 100% unrelated to the problem. Instead, the following 13 lines is enough to make a multiple page PDF:
//Create a sample multiple page PDF and place it on the desktop
var outputFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "t5.pdf");
using (var fs = new FileStream(outputFile, FileMode.Create, FileAccess.Write, FileShare.None)) {
using (var doc = new Document()) {
using (var writer = PdfWriter.GetInstance(doc, fs)) {
doc.Open();
for (var i = 0; i < 1000; i++) {
doc.Add(new Paragraph(String.Format("This is paragraph #{0}", i)));
}
doc.Close();
}
}
}
Second, get rid of try/catch. Those are great for production (sometimes) but at the development level that's why we have IDEs and compilers, they'll tell us specifically what's wrong.
Now on to the bigger problem, you need to keep these two processes separate from each other. Every single brace and object from part part #1 must be closed, done and accounted for. Part #2 then needs to be fed a completely valid PDF but neither of the two parts should be "aware" of each other or depend on each other.
Since you just borrowed some code that wasn't intended for what you're trying to do I'm going to also ignore that and use some code that I know specifically will work. Also, since you're open to using a MemoryStream in the first place I'm just going to avoid writing to disk until I need to. Below is a full working sample that creates a multiple page and then adds page numbers in a second pass.
//Will hold our PDF as a byte array
Byte[] bytes;
//Create a sample multiple page PDF, nothing special here
using (var ms = new MemoryStream()) {
using (var doc = new Document()) {
using (var writer = PdfWriter.GetInstance(doc, ms)) {
doc.Open();
for (var i = 0; i < 1000; i++) {
doc.Add(new Paragraph(String.Format("This is paragraph #{0}", i)));
}
doc.Close();
}
}
//Store our bytes before
bytes = ms.ToArray();
}
//Read our sample PDF and apply page numbers
using (var reader = new PdfReader(bytes)) {
using (var ms = new MemoryStream()) {
using (var stamper = new PdfStamper(reader, ms)) {
int PageCount = reader.NumberOfPages;
for (int i = 1; i <= PageCount; i++) {
ColumnText.ShowTextAligned(stamper.GetOverContent(i), Element.ALIGN_CENTER, new Phrase(String.Format("Page {0} of {1}", i, PageCount)), 100, 10 , 0);
}
}
bytes = ms.ToArray();
}
}
var outputFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "t5.pdf");
System.IO.File.WriteAllBytes(outputFile, bytes);
I'm having an issue with flattening fields that were generated in a table cell. I've created a sample project to illustrate the issue.
private static void dummyFunction2()
{
// Create a PDF with a TextBox in a table cell
//Get the font ready
BaseFont bfHelvetica = BaseFont.CreateFont(BaseFont.HELVETICA, BaseFont.CP1250, false);
var helvetica12 = new Font(bfHelvetica, 12, Font.NORMAL, BaseColor.BLACK);
//Create the document and filestream
var doc = new Document(PageSize.LETTER, 18f, 18f, 18f, 18f);
var fs = new FileStream("TextBoxInTableCell.pdf", FileMode.Create);
PdfWriter writer = PdfWriter.GetInstance(doc, fs);
//Create the table
doc.Open();
var myTable = new PdfPTable(1);
myTable.TotalWidth = 568f;
myTable.LockedWidth = true;
myTable.HorizontalAlignment = 0;
//Create the textfield that will sit on a cell in the table
var tf = new TextField(writer, new Rectangle(67, 585, 140, 800), "cellTextBox");
tf.Text = "test";
//Create the table cell
var tbCell = new PdfPCell(new Phrase(" ", helvetica12));
//Use fieldpositioningevents to make the field appear on top of the cell
var events =
new FieldPositioningEvents(writer, tf.GetTextField());
tbCell.CellEvent = events;
//Add the cell to the table
myTable.AddCell(tbCell);
PdfContentByte cb = writer.DirectContent;
//Write out the table to the middle of the document
myTable.WriteSelectedRows(0, -1, 0, -1, 0, 400, cb);
doc.Close();
fs.Close();
//Open back up the document so that we can set GenerateAppearances to false.
//This solution proposed and accepted at https://stackoverflow.com/questions/25169342/itextsharp-fields-generated-in-a-table-not-shown-in-adobe-reader
var reader2 = new PdfReader("TextBoxInTableCell.pdf");
var stamper2 = new PdfStamper(reader2, new FileStream("tempdoc.pdf", FileMode.Create));
stamper2.AcroFields.GenerateAppearances = false;
stamper2.Close();
reader2.Close();
Process.Start("tempdoc.pdf");
//Open the pdf back up
var reader = new PdfReader("tempdoc.pdf");
var stamper = new PdfStamper(reader, new FileStream("tempdoc.pdf" + "1.pdf", FileMode.Create));
//Flatten the form
stamper.FormFlattening = true;
//Close everything
stamper.Close();
reader.Close();
Process.Start("tempdoc.pdf" + "1.pdf");
}
This unflattened pdf that is generated looks like . As you can see, the field is where it should be. The flattened pdf, however, looks like . The field's text has been shifted a noticeable amount.
I've posted the flattened pdf so that someone can check out the pdf language if needed.
I know this is sort of a niche issue but hopefully someone can help me out.
EDIT1: In response to Bruno's comment, I'm using iTextsharp 5.5.2 downloaded from Nuget and the unflattened pdf can be found here.
EDIT2: Updated SO link to point to the correct question. For reference here are my two previous questions that relate to this problem: First, Second
Java version of iText does not contain this problem. It's a Java -> C# porting issue. We'll take care of that.
Using .NET, I want to programmatically create a PDF which simply consists of a background image with two labels over it with different fonts and positioning. I have read about existing PDF libraries, but don't know (if applicable) which one is the easiest for such a simple task.
Anyone care to guide me?
P.D.: I do not want to create the PDF with a generated image that already overlays the text over the background image.
Edit: This is the final working code:
public string Create()
{
if (!Directory.Exists(ApplicationImagePath))
{
Directory.CreateDirectory(ApplicationImagePath);
}
// Smart card
var doc = new Document(PageSize.GetRectangle("153 242.65"), 0, 0, 0, 0);
using (var stream = File.Create(filepath))
{
var writer = PdfWriter.GetInstance(doc, stream);
doc.Open();
var image = Image.GetInstance(CarnetData.Frame, ImageFormat.Png);
image.Alignment = Element.ALIGN_CENTER;
image.ScaleToFit(153, 242.65f);
doc.Add(image);
BaseFont font = BaseFont.CreateFont(GetFontPath(CarnetConfiguration.FontType), BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
font.PostscriptFontName = CarnetConfiguration.FontType.ToString();
float verticalPosition = writer.GetVerticalPosition(false);
var pName = new Paragraph(CarnetData.Name, new Font(font, FontData.EmployeeFont.SizeInPoints))
{
SpacingBefore = verticalPosition - 51f,
MultipliedLeading = 1.1f,
Alignment = Element.ALIGN_CENTER
};
doc.Add(pName);
var pDepartment = new Paragraph(CarnetData.Department, new Font(font, FontData.DepartmentFont.SizeInPoints))
{
SpacingBefore = 1.5f,
MultipliedLeading = 1.2f,
Alignment = Element.ALIGN_CENTER
};
doc.Add(pDepartment);
writer.ViewerPreferences = PdfWriter.PageModeUseNone + PdfWriter.CenterWindow + PdfWriter.PageLayoutSinglePage;
doc.Close();
}
return filepath;
}
Thanks for the help. :)
iTextSharp is a great library you could use, very simple and intuitive:
var doc = new Document();
using (var stream = File.Create("output.pdf"))
{
var writer = PdfWriter.GetInstance(doc, stream);
doc.Open();
doc.Add(Image.GetInstance(#"c:\foo\test.png"));
var cb = writer.DirectContent;
cb.BeginText();
cb.SetTextMatrix(100, 220);
var font = BaseFont.CreateFont(BaseFont.TIMES_ROMAN, BaseFont.CP1252, false);
cb.SetFontAndSize(font, 12);
cb.ShowText("Hello World");
cb.EndText();
cb.BeginText();
cb.SetTextMatrix(100, 250);
cb.ShowText("Some other text");
cb.EndText();
doc.Close();
}
Use iTextSharp. Free.
#binaryhowl - You can try Syncfusion PDF. It is great component with excellent support
http://asp.syncfusion.com/sfaspnetsamplebrowser/9.1.0.20/Web/Pdf.Web/samples/4.0/
I created a simple pdf with iText.
But why is the position of the text on the first page higher than on all the other pages.
Here is some test code to see where the problem situates:
MemoryStream PDFData = new MeMemoryStream PDFData = new MemoryStream();
Document document = new Document(PageSize.A4, 50, 50, 80, 50);
PdfWriter PDFWriter = PdfWriter.GetInstance(document, PDFData);
document.Open();
Moviecollection movCol = new Moviecollection();
foreach (Movie mov in movCol.Movies)
{
Phrase phr = new Phrase(mov.Description);
document.Add(phr);
document.Add(Chunk.NEWLINE);
}
document.Close();
Any ideas?
thanks,
Filip
I think its to do with Chunk.NEWLINE addition.
I'm guessing you are simulating a paragraph with that Phrase + Newline combination. If you switch to Paragraph object instead, the problem is solved (tested on my machine with your code).
using(MemoryStream PDFData = new MemoryStream())
using(Document document = new Document(PageSize.A4, 50, 50, 80, 50))
{
PdfWriter PDFWriter = PdfWriter.GetInstance(document, PDFData);
document.Open();
Moviecollection movCol = new Moviecollection();
foreach (Movie mov in movCol.Movies)
document.Add(new Paragraph(mov.Description));
}