|
Introduction
This is my second article towards creating PDF files. The earlier one employed on simple text and this version in C# can add tables to the PDF files. This library can be used for simple HTML conversion, or conversion from other documents if you know that document format. At present, it can add only tables, and create PDF document with any number of pages.
Let us begin by using the library. Download the library and add a reference to the library in your .NET project.
Creating a PDF Document
Creating a PDF document can be divided into three steps.
- Writing the header of the PDF file.
- Creating pages of the document.
- Add text.
- Add table.
- Finish the document.
In each step, you open a file specifying the output file name. In the first step, it's is opened as create, and in every other step it is open as append. In PDF format, every object we create and write are referenced by the byte offset of that object within the file.
Step One
I will go by explaining the code sample for using the PDF library.
CatalogDict catalogDict=new CatalogDict();
PageTreeDict pageTreeDict=new PageTreeDict();
FontDict TimesRoman=new FontDict();
FontDict TimesItalic=new FontDict();
InfoDict infoDict=new InfoDict();
TimesRoman.CreateFontDict("T1","Times-Roman");
TimesItalic.CreateFontDict("T2","Times-Italic");
infoDict.SetInfo("title","author","company");
Utility pdfUtility=new Utility();
FileStream file=new FileStream(@"c:\text.pdf",FileMode.Create);
int size=0;
file.Write(pdfUtility.GetHeader("1.5",out size),0,size);
file.Close();
Create the pages in the document. Here we are creating only one page. This process can be repeated to include any number of pages. A page will have its contents. Contents are the text and table that we create. This content is an object of the type ContentDict. A page can have any number of ContentDicts, but two or more pages cannot have the same ContentDict.
Every page must be added to the PageTreeDict. This is the RootNode of the pages in the PDF Document structure. In a PDF document, there will be only one PageTree (created with this library). This is created by using PageTreeDict.AddPage(). The order of the page in the document will be in the order how there were added to the PageTree.
To every page, resources must be added. These resource include the font that must be used inside the page and the objects of the ContentDict. This is done by calling PageDict.AddResource. The font types that are to be used are specified in the library. In this library, only fonts of type Times New Roman will be correctly centered and right aligned. This is because, for aligning, we must have the width of all the character glimpses. I have stored only the width of Times New Roman.
In AddPage, we specify the objNum of the page to be added, and in AddResource, we add the objNum of the ContentDict.
For adding text and tables in the page, create an object of type TextAndTables. For adding text, call addText specifying the X and Y coordinates.
For adding table, first fill the parameters of the table using TableParams. In the constructor, specify the number of columns and their widths. If the widths are same then you can use the other constructor just specifying the number of columns and setting the numColumns parameter of the structure. In this version, only the three parameters of the table need to be set, they are:
- row height
- X coordinate
- Y coordinate
Now, we can specify the alignment of each text within a cell. If we have two columns, create an array of two Align elements.
After this much initialization, call the TextAndTable.AddRow() member. This can be called as many times as to add new rows. When finished, call EndTable(). This will return a string. This string should be passed to content.SetStream().
Now add these things to the file. Then we have finished our second step.
PageDict page=new PageDict();
ContentDict content=new ContentDict();
PageSize pSize=new PageSize(612,792);
pSize.SetMargins(10,10,10,10);
page.CreatePage(pageTreeDict.objectNum,pSize);
pageTreeDict.AddPage(page.objectNum);
page.AddResource(TimesRoman,content.objectNum);
TextAndTables textAndtable=new TextAndTables(pSize);
textAndtable.AddText(20,10,"Testing",10,"T1",Align.CenterAlign);
Align[] align=new Align[2];
align[0]=Align.LeftAlign;
align[1]=Align.LeftAlign;
ColorSpec cellColor=new ColorSpec(100,100,100);
ColorSpec lineColor=new ColorSpec(98,200,200);
TableParams table=new TableParams(2,200,200);
table.yPos=700;
table.xPos=100;
table.rowHeight=20;
textAndtable.SetParams(table,cellColor,Align.CenterAlign,3);
textAndtable.AddRow(false,10,"T1",align,"First Column","Second Column");
textAndtable.AddRow(false,10,"T1",align,"Second Row","Second Row");
content.SetStream(textAndtable.EndTable(lineColor));
content.SetStream(textAndtable.EndText());
size=0;
file=new FileStream(@"c:\text.pdf",FileMode.Append);
file.Write(page.GetPageDict(file.Length,out size),0,size);
file.Write(content.GetContentDict(file.Length,out size),0,size);
file.Close();
Step Three
Now that we have finished the creation of the page, we can end the creation of the PDF document. This is done by writing every piece of information to the file.
file=new FileStream(@"c:\text.pdf",FileMode.Append);
file.Write(catalogDict.GetCatalogDict(pageTreeDict.objectNum,
file.Length,out size),0,size);
file.Write(pageTreeDict.GetPageTree(file.Length,out size),0,size);
file.Write(TimesRoman.GetFontDict(file.Length,out size),0,size);
file.Write(TimesItalic.GetFontDict(file.Length,out size),0,size);
file.Write(infoDict.GetInfoDict(file.Length,out size),0,size);
file.Write(pdfUtility.CreateXrefTable(file.Length,out size),0,size);
file.Write(pdfUtility.GetTrailer(catalogDict.objectNum,
infoDict.objectNum,out size),0,size);
file.Close();
Testing
All the code above is included inside a single function. Usually, for creating HTML files, the steps one and three will be done only once, but step two will be repeated many times. You can use this library and clarify any doubts as you go using this. Try experimenting with this.
Conclusion
This is a very basic library for creating PDF files. Once you know the PDF format, you can modify the library to include many more features like drawing lines and circles. Actually, the project I have been working only required simple tables to be added to the PDF files. That's is why I had to limit to only that feature.
| You must Sign In to use this message board. |
|
| | Msgs 1 to 25 of 132 (Total in Forum: 132) (Refresh) | FirstPrevNext |
|
 |
|
|
 |
|
|
i am trying to pass a string that is along the lines of "Some text\tThis should be tabbed over." The raw file (opened in Notepad++) has the tab, but when it is opened in Adobe it does not show. Is there a way to do this or will i have to figure this out differently? I have not found any information in the Adobe pdf reference, so i am turning here to see if i can get help with this. EDIT: this is a code sample that i am trying to get working
String Title = "CreatePdfReport"; String Author = "Joe Coder"; String Company = "fakerSoft, Inc.";
////// // Open New Document //// catalogDict = new CatalogDict(); pageTreeDict = new PageTreeDict(); TimesNormal = new FontDict(); infoDict = new InfoDict(); TimesNormal.CreateFontDict("T1", "Times-Roman"); infoDict.SetInfo(Title, Author, Company); pdfUtility = new Utility(); string newPath = System.IO.Path.Combine(this.Path, this.DocumentName); //Open a fs specifying the fs name as the output pdffile fs = new FileStream(newPath, FileMode.Create); size = 0; fs.Write(pdfUtility.GetHeader("1.5", out size), 0, size);
////// // Open a New Page //// page = new PageDict(); content = new ContentDict(); page.CreatePage(pageTreeDict.objectNum, pSize); pageTreeDict.AddPage(page.objectNum); page.AddResource(TimesNormal, content.objectNum);
////// // Open A TextAndTable Block //// textAndtable = new TextAndTables(pSize);
////// // Write Line with a Tab Character in it. //// string text = "This Should have a\tTab in the middle."; textAndtable.AddText(72, 72, text, (uint)this.Font.Size, "T1", Align.LeftAlign);
////// //End Text Entry //// content.SetStream(textAndtable.EndText());
////// // End Page //// size = 0; fs.Write(page.GetPageDict(fs.Length, out size), 0, size); fs.Write(content.GetContentDict(fs.Length, out size), 0, size);
////// // End Document //// size = 0; fs.Write(catalogDict.GetCatalogDict(pageTreeDict.objectNum, fs.Length, out size), 0, size); fs.Write(pageTreeDict.GetPageTree(fs.Length, out size), 0, size); fs.Write(TimesNormal.GetFontDict(fs.Length, out size), 0, size); fs.Write(TimesBold.GetFontDict(fs.Length, out size), 0, size); fs.Write(TimesItalic.GetFontDict(fs.Length, out size), 0, size); fs.Write(TimesBoldItalic.GetFontDict(fs.Length, out size), 0, size); fs.Write(CourierNormal.GetFontDict(fs.Length, out size), 0, size); fs.Write(CourierBold.GetFontDict(fs.Length, out size), 0, size); fs.Write(CourierItalic.GetFontDict(fs.Length, out size), 0, size); fs.Write(CourierBoldItalic.GetFontDict(fs.Length, out size), 0, size); fs.Write(ArialNormal.GetFontDict(fs.Length, out size), 0, size); fs.Write(ArialBold.GetFontDict(fs.Length, out size), 0, size); fs.Write(ArialItalic.GetFontDict(fs.Length, out size), 0, size); fs.Write(ArialBoldItalic.GetFontDict(fs.Length, out size), 0, size); fs.Write(infoDict.GetInfoDict(fs.Length, out size), 0, size); fs.Write(pdfUtility.CreateXrefTable(fs.Length, out size), 0, size); fs.Write(pdfUtility.GetTrailer(catalogDict.objectNum, infoDict.objectNum, out size), 0, size); fs.Close(); fs = null;
-t
modified on Tuesday, August 26, 2008 8:21 AM
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Hi , i am trying to save a pdf file using greek letters. So far nothing that i have tried work. Any thoughts or better solutions.;;
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Hello,
I've downloaded the PdfLibrary from this article:
http://www.codeproject.com/KB/dotnet/PdfLibrary/PdfLibrary_src.zip
And without changing anything I've execute the code like the description tells. The pdf is created but when opening the file I got the Error, that the token 0,384 was not found. And the pdfDocument is one empty page.
The code is posted some years ago, is there a pdf-reader version problem? Has someone testet this, or can test it and tell me if there is the problem too?
I would be glad if someone could tell...
greetings Sotiris
|
| Sign In·View Thread·PermaLink | 2.00/5 (1 vote) |
|
|
|
 |
|
|
Thanks for sharing such a great information.
However, I'm unable to create a pdf with multiple pages. Would you mind to share with me? Thanks so much.
|
| Sign In·View Thread·PermaLink | 1.00/5 (1 vote) |
|
|
|
 |
|
|
Hello,
I've downloaded the PdfLibrary from this article:
http://www.codeproject.com/KB/dotnet/PdfLibrary.aspx#xx2493698xx[^]
And without changing anything I've execute the code like the description tells. The pdf is created but when opening the file I got the Error, that the token 0,384 was not found. And the pdfDocument is one empty page.
The code is posted some years ago, is there a pdf-reader version problem? Has someone testet this, or can test it and tell me if there is the problem too?
I would be glad if someone could tell...
greetings Adriane
|
| Sign In·View Thread·PermaLink | 5.00/5 (1 vote) |
|
|
|
 |
|
|
 |
|
|
Hello,
I have some data in my database. It may contains some pics,paragraph, or aligined texts.. these data are resides under some topics if i select some of the topic i have to fetch the data In a printable format(means aligined format) in to a pdf page. i mean the dynamic printing.. i am using asp.net c# sqlserver..] Thanking you...
|
| Sign In·View Thread·PermaLink | 1.50/5 (2 votes) |
|
|
|
 |
|
|
I tried to generate multiple pdf pages, but the datas are not showing? Can anyone tell what will be the issue?
|
| Sign In·View Thread·PermaLink | 1.00/5 (5 votes) |
|
|
|
 |
|
|
Hi,
Really helpful code to create a pdf without using any 3rd party dll. When i try to create table with more than 2 columns it is throwing Index out of bound exception. Can u send me a sample code which can create a table with more than 2 cols. My requirement is that it can have N no. of columns.
Thanks in advance,
Regards,
Shubhee
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Hi, Really fantastic piece of code to create a pdf without using any 3rd party dll. When i try to create table with >2 columns it is throwing Index out of bound exception. Can u send me a sample code which can create a table with 6 x 30 columns.
Thanks in advance,
Regards, Swathi
|
| Sign In·View Thread·PermaLink | 4.25/5 (3 votes) |
|
|
|
 |
|
|
i am using your code. i want to print barcode on the pdf file using your code. for this i am using the font Free 3 of 9. But it is not showing on the PDF file. please help me out. what is the problem? any font other than free 3 of 9 is working fine. why that font is not applying? i installed free 3 of 9 in my system.
thanks -Praveen
|
| Sign In·View Thread·PermaLink | 1.00/5 (3 votes) |
|
|
|
 |
|
|
 |
|
|
I found an amazing html to pdf converter library for .net at http://www.dotnet-reporting.com , is the same. It has full support for HTML tags and CSS and I created a PDF report from a ASP.NET page in a few minutes. That would have taken ages with other reporting tools.
Here are a few lines of code that I used to create the report
PdfConverter pdfConverter = new PdfConverter(); pdfConverter.PdfDocumentOptions.PdfPageSize = PdfPageSize.A4; pdfConverter.PdfDocumentOptions.PdfPageOrientation = PDFPageOrientation.Portrait; pdfConverter.PdfDocumentOptions.PdfCompressionLevel = PdfCompressionLevel.Normal; pdfConverter.PdfDocumentOptions.GenerateSelectablePdf = true; pdfConverter.PdfDocumentOptions.ShowFooter = false; pdfConverter.PdfDocumentOptions.ShowHeader = false; pdfConverter.LicenseFilePath = Server.MapPath(@"~/Bin" ; byte[] downloadBytes = pdfConverter.GetPdfFromUrlBytes(MyURL);
There are other interesting PDF tools there like PDF MErge, PDF Split, RTF to PDF Converter, PDF Security tools .
Regards, Florin
-- modified at 16:00 Sunday 8th July, 2007
|
| Sign In·View Thread·PermaLink | 1.08/5 (6 votes) |
|
|
|
 |
|
|
 |
|
|
 |
|
|
I would like to find a programmer that can put a PDF form on my website to be completed by visitors who would be allowed to make a copy of the completed form, print the completed form and I would save the completed form on my site.
My site is constructed in Visual Studio.Net with Basic.
Can this be done? Can you advise as to whom to contact to do such a job?
|
| Sign In·View Thread·PermaLink | 1.33/5 (2 votes) |
|
|
|
 |
|
|
Hi
If you want you can make the users fill a html form in your site and then have the option to export that to the pdf file using this library. This article is all about this.
Regards
The Best Religion is Science. Once you understand it, you will know God.
|
| Sign In·View Thread·PermaLink | 5.00/5 (1 vote) |
|
|
|
 |
|
|
Hi,
If you need a professional library for .NET that converts ASP.NET / HTML pages or only html strings to pdf, here is an interesting tool: www.html-to-pdf.net
Here is some code example:
PdfConverter pdfConverter = new PdfConverter();
pdfConverter.PdfDocumentOptions.PdfPageSize = PdfPageSize.A4; pdfConverter.PdfDocumentOptions.PdfCompressionLevel = PdfCompressionLevel.Normal; pdfConverter.PdfDocumentOptions.ShowHeader = true; pdfConverter.PdfDocumentOptions.ShowFooter = true; pdfConverter.PdfDocumentOptions.LeftMargin = 5; pdfConverter.PdfDocumentOptions.RightMargin = 5; pdfConverter.PdfDocumentOptions.TopMargin = 5; pdfConverter.PdfDocumentOptions.BottomMargin = 5; pdfConverter.PdfDocumentOptions.UseMetafileFormat = true;
pdfConverter.PdfDocumentOptions.ShowHeader = false; //pdfConverter.PdfHeaderOptions.HeaderText = "Sample header: " + TxtURL.Text; //pdfConverter.PdfHeaderOptions.HeaderTextColor = Color.Blue; //pdfConverter.PdfHeaderOptions.HeaderDescriptionText = string.Empty; //pdfConverter.PdfHeaderOptions.DrawHeaderLine = false;
pdfConverter.PdfFooterOptions.FooterText = "Sample footer: " + TxtURL.Text + ". You can change color, font and other options"; pdfConverter.PdfFooterOptions.FooterTextColor = Color.Blue; pdfConverter.PdfFooterOptions.DrawFooterLine = false; pdfConverter.PdfFooterOptions.PageNumberText = "Page"; pdfConverter.PdfFooterOptions.ShowPageNumber = true;
pdfConverter.LicenseFilePath = System.IO.Path.Combine(Server.MapPath("~"), "Bin"); byte[] downloadBytes = pdfConverter.GetPdfFromUrlBytes(url);
System.Web.HttpResponse response = System.Web.HttpContext.Current.Response; response.Clear(); response.AddHeader("Content-Type", "binary/octet-stream"); response.AddHeader("Content-Disposition", "attachment; filename=" + downloadName + "; size=" + downloadBytes.Length.ToString()); response.Flush(); response.BinaryWrite(downloadBytes); response.Flush(); response.End();
The document rendered is almost perfect.
|
| Sign In·View Thread·PermaLink | 1.00/5 (6 votes) |
|
|
|
 |
|
|
Hi
Thats cool, but its not free 
Regards
The Best Religion is Science. Once you understand it, you will know God.
|
| Sign In·View Thread·PermaLink | 1.00/5 (2 votes) |
|
|
|
 |
|
|
How much money is this company paying you for advertising ? Or do you work for this company ? Have in mind that CodeProject is a place for sharing code, not for selling your stuff.
I have seen your comments (the same advertising sh@t) in several articles.
Alexander German
|
| Sign In·View Thread·PermaLink | 3.17/5 (4 votes) |
|
|
|
 |
|
|
It's a nice thing you've done going through PDF doc specification and implement it in C#.
But.... the way you implemented it is ridiculous. I would recommend any one who is going to use that code in production to completely rewrite it. 1. All those multiple opening/closing files are not necessary. 2. You do not need to create an object to call it's method if it's not using members. Just declare that method as "static". So not more code like that StraighLine ln = new StraightLine(); Ln.DrawLine(..);
Instead you can write StraightLine.DrawLine(..).
3. Use StringBuilder for extensive string concatenation.
Your code would pollute memory so bad if you try to create more than 1 PDF file, your server will be on it's knees begging for mercy.
Do not get me wrong, I am very gratefull that you took time to learn PDF specs. But you really need to polish your .NET skills.
Thanks George.
-- modified at 8:55 Monday 21st May, 2007
|
| Sign In·View Thread·PermaLink | 1.00/5 (1 vote) |
|
|
|
 |
|
|
Hi
Thankyou for pointing out those mistakes. This was my first and the last c# program ever written.
>> I would recommend any one who is going to use that code in production to completely rewrite it.
Me too.
Regards
The Best Religion is Science. Once you understand it, you will know God.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Hi Zainu
Excellent article. It has helped me a lot.
I have added the functionality to create jpg images and also use cubic bezier curves to create 'round rectangles' suitable for invoice creation etc.
As there seems to be a lot of requests for adding images to a pdf, I am thinking of submitting a new article to show how to do this. However, as this is based on your work, I thought I better ask if you would mind me using this article as the basis before I go ahead. If you could reply to this, or send me an email (I think there is a contact me link below) I'd appreciate it.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
Hi
That would be really great.
Go ahead,
Regards
The Best Religion is Science. Once you understand it, you will know God.
|
| Sign In·View Thread·PermaLink | 2.00/5 (1 vote) |
|
|
|
 |
|
|
General News Question Answer Joke Rant Admin
|