📜 ⬆️ ⬇️

When to make a PDF document

If you are faced with the task of creating unpretentious (or not quite) pdf documents in your application - these may be reports and recipes, well, or you will want to print information about your objects in this way, then you can use, for example, the installed OpenOffice and its capabilities (it's hard ), and you can use the iTextSharp library (Free C # -PDF library), that's what I want to give you a small example, with which I will create such a document:


There are many ways to create pdf documents using this library. I liked the way I described it most with the xml document . I decided to create such xml with xslt conversion, and send the data with an xml document.

Our data will look like this:
<? xml version ="1.0" encoding ="utf-8" ? >
< Profile >
< FirstName > </ FirstName >
< SecondName > </ SecondName >
< LastName > </ LastName >
< Subtexts >
< Text > . . . . . . . . </ Text >
</ Subtexts >
< Subtexts >
< Text > . . . . . . . . . </ Text >
</ Subtexts >
</ Profile >


* This source code was highlighted with Source Code Highlighter .
Next, we need to create xml for pdf (I will say that the link to iText.dtd scheme in the tutorial document is broken, I provide the correct link below), as I said above for this, we will write the xslt conversion :
<? xml version ="1.0" encoding ="utf-8" ? >
< xsl:stylesheet version ="1.0" xmlns:xsl ="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl ="urn:schemas-microsoft-com:xslt" exclude-result-prefixes ="msxsl" >
< xsl:param name ="picturePath" />
< xsl:output method ="xml" indent ="yes" />

< xsl:template match ="/Profile" >
< itext >
< paragraph align ="Center" >
< phrase fontstyle ="bold" size ="16.0" > </ phrase >
</ paragraph >

< image >
< xsl:attribute name ="url" >
< xsl:value-of select ="$picturePath" />
</ xsl:attribute >
</ image >

< table width ="100%" columns ="3" cellpadding ="1" cellspacing ="1" borderwidth ="0.5" red ="0"
green ="0" blue ="0" left ="true" right ="true" top ="true" bottom ="true" widths ="33;33;33" >
< row >
< cell borderwidth ="0.5" red ="0" green ="0" blue ="0" left ="false"
right ="true" top ="false" bottom ="true" header ="true" horizontalalign ="Center" >
< phrase size ="10.0" > </ phrase >
</ cell >
< cell borderwidth ="0.5" red ="0" green ="0" blue ="0" left ="false"
right ="true" top ="false" bottom ="true" header ="true" horizontalalign ="Center" >
< phrase size ="10.0" > </ phrase >
</ cell >
< cell borderwidth ="0.5" red ="0" green ="0" blue ="0" left ="false"
right ="false" top ="false" bottom ="true" header ="true" horizontalalign ="Center" >
< phrase size ="10.0" > </ phrase >
</ cell >
</ row >
< row >
< cell borderwidth ="0.5" red ="0" green ="0" blue ="0" left ="false"
right ="true" top ="false" bottom ="false" header ="false" horizontalalign ="Left" >
< phrase size ="10.0" >
< xsl:value-of select ="FirstName" />
</ phrase >
</ cell >
< cell borderwidth ="0.5" red ="0" green ="0" blue ="0" left ="false"
right ="true" top ="false" bottom ="false" header ="false" horizontalalign ="Left" >
< phrase size ="10.0" >
< xsl:value-of select ="SecondName" />
</ phrase >
</ cell >
< cell borderwidth ="0.5" red ="0" green ="0" blue ="0" left ="false"
right ="false" top ="false" bottom ="false" header ="false" horizontalalign ="Left" >
< phrase size ="10.0" >
< xsl:value-of select ="LastName" />
</ phrase >
</ cell >
</ row >
</ table >

< xsl:apply-templates select ="Subtexts" />

</ itext >
</ xsl:template >

< xsl:template match ="Subtexts" >
< paragraph align ="Justify" >
< phrase size ="14.0" >
< xsl:value-of select ="Text" />
</ phrase >
</ paragraph >
< newline />
</ xsl:template >

</ xsl:stylesheet >


* This source code was highlighted with Source Code Highlighter .
For me, the description scheme they chose was not the most successful one, too, a loud code is obtained for a small pdf document. So, it is not very familiar to describe the colors of red green and blue separately from each other, so it would be possible to make them in the HEX record. As can be seen in the xslt scheme - there is a parameter in the document that indicates the path of the picture, which will be inserted into our pdf document, as there is a table consisting of 3 columns and a couple of paragraphs described by the scheme.
Next step: we describe all the code that will return us an array of bytes of our pdf document, with comments I tried to describe the whole sequence of actions:
public byte [] GetPdfRaw()
{
XmlDocument doc = new XmlDocument ();
// xml
doc.Load(MapPath( @"~\Resources\UserProfile.xml" ));
XslCompiledTransform xslTransform = new XslCompiledTransform();
// XSLT
xslTransform.Load(MapPath( @"~\Resources\ReportProcessor.xslt" ));
XsltArgumentList list = new XsltArgumentList();
//
list.AddParam( "picturePath" , string .Empty, MapPath( @"~\Resources\Toco.jpg" ));
// , xml pdf
using (MemoryStream stream = new MemoryStream())
{
// xml pdf
xslTransform.Transform(doc, list, stream);

// Font pdf
BaseFont baseFont = BaseFont.CreateFont(Environment.ExpandEnvironmentVariables( @"%systemroot%\fonts\Tahoma.TTF" ),
"CP1251" , BaseFont.EMBEDDED);

// PDF
Document document = new Document();
using (MemoryStream pdfStream = new MemoryStream())
{
PdfWriter.GetInstance(document, pdfStream);
XmlDocument d = new XmlDocument ();
string str = Encoding .UTF8.GetString(stream.ToArray()).Substring(1);
d.LoadXml(str);
// xml pdf
ITextHandler h = new ITextHandler(document) {DefaultFont = baseFont};
h.Parse(d);
// pdf byte[]
return pdfStream.ToArray();
}
}
}


* This source code was highlighted with Source Code Highlighter .
I want to draw attention to the definition of baseFont and install it as a default font for ITextHandler. If this procedure is not performed, then Cyrillic will not be displayed. This approach allows you to display Cyrillic, but does not allow us to use multiple fonts in one document. In their code (the source code is good) they always take codepage 1252 (directly hardcoded into the code), so if you need to use several fonts in one document, then correct the code and build the library itself, or do not use xml as the source Data (but not the fact that the problem is only in ITextHandler).
Still very interested in why they are sometimes called classes with the letter I, in c # interfaces are so called. Of course, I understand that the library is ported from java, but still - it introduced me first into a stupor ...
The last is the output of the pdf document in the Response page (if you have an ASP.NET application like mine)
protected override void OnLoad( EventArgs e)
{
// Response pdf , MIME
HttpContext .Current.Response.Clear();
HttpContext .Current.Response.ContentType = "application/pdf" ;
HttpContext .Current.Response.AddHeader( "Content-Disposition" , string .Format( "attachment;filename=\"{0}\"" , "report.pdf" ));
byte [] pdfRaw = GetPdfRaw();
HttpContext .Current.Response.OutputStream.Write(pdfRaw, 0, pdfRaw.Length);
}


* This source code was highlighted with Source Code Highlighter
Download the example ... (for the work of the example, you must also download the library itextsharp, the example uses version 4.1.2.0)

Related Links:

')

Source: https://habr.com/ru/post/56973/


All Articles