Generate PDF In Windows 8.1

Introduction

The main aim of this article is to generate a PDF according to our requirement in Universal Windows App. So far so many APIs  are there to generate PDFs but do not support Windows environment. You can get more information from msdn How to generate PDF on Windows Phone in VB or C#.

 

Now, I’m going to create a Project with Employee Information as an example to generate the Selected Employee Details as a PDF.

Step 1: Open Visual Studio 2013, click New Project, choose Windows Apps, select Blank App, and name as GeneratePdfFile. After that click OK.

Step 2:

Add a Class, name it as Employee and add the following code. This contains two classes i.e Employee and EmployeeModel; Employee class is having all the properties and EmployeeModel contains all the Methods to access the employee data.

  1. public class Employee   
  2. {  
  3.   
  4.     public int EmployeeId  
  5.   {  
  6.         get;  
  7.         set;  
  8.     }  
  9.     public string EmployeeName  
  10.     {  
  11.         get;  
  12.         set;  
  13.     }  
  14.     public string Designation  
  15.     {  
  16.         get;  
  17.         set;  
  18.     }  
  19.     public string Salary   
  20.     {  
  21.         set;  
  22.         get;  
  23.     }  
  24.     public string PhoneNumber   
  25.     {  
  26.         get;  
  27.         set;  
  28.     }  
  29.   
  30. }  
  31.   
  32. public class EmployeeModel  
  33. {  
  34.     List < Employee > emp = new List < Employee > ();  
  35.     public List < Employee > GetAllEmployees()  
  36.     {  
  37.         emp.Add(newEmployee()   
  38.          {  
  39.             EmployeeId = 101, EmployeeName = "uday", Designation = "Developer", Salary = "30000", PhoneNumber = "9xxxxxxxx9"  
  40.         });  
  41.   
  42.         emp.Add(new Employee()   
  43.          {  
  44.             EmployeeId = 102, EmployeeName = "Stephen", Designation = "Developer", Salary = "20000", PhoneNumber = "8xxxxxxxx9"  
  45.         });  
  46.         emp.Add(new Employee()  
  47.          {  
  48.             EmployeeId = 103, EmployeeName = "Tom", Designation = "Tester", Salary = "35000", PhoneNumber = "6xxxxxxxx9"  
  49.         });  
  50.         emp.Add(new Employee()   
  51.         {  
  52.             EmployeeId = 104, EmployeeName = "Sathish", Designation = "Architect", Salary = "50000", PhoneNumber = "7xxxxxxxx9"  
  53.         });  
  54.   
  55.         return emp;  
  56.   
  57.     }  
  58.   
  59.     public Employee GetEmployeeById(int Id)  
  60.   
  61.     {  
  62.   
  63.         Employee _emp = emp.SingleOrDefault(xl => xl.EmployeeId == Id);  
  64.   
  65.         return _emp;  
  66.     }  
  67. }  
  68. }  

Step 3: In MainPage.Xaml.Cs add the following code to display the data in a List View.

  1. public sealed partial class MainPage: Page  
  2.   
  3. {  
  4.   
  5.     EmployeeModel _empModel;  
  6.   
  7.     Employee emp;  
  8.   
  9.     public MainPage()  
  10.   
  11.     {  
  12.   
  13.         this.InitializeComponent();  
  14.   
  15.         _empModel = new EmployeeModel();  
  16.   
  17.         emp = new Employee();  
  18.   
  19.         this.DataContext = _empModel.GetAllEmployees();  
  20.   
  21.     }  
  22.   
  23.  

Step 4: In order to display the data I used Data Binding concept. Now in MainPage.Xaml add the following code. Add this line in the beginning of the url: 

  1. DataContext="{Binding EmployeeModel, RelativeSource={RelativeSource Self}}"  

Then add the following code,

  1. <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">  
  2.   
  3.     <Grid.RowDefinitions>  
  4.   
  5.         <RowDefinition Height="Auto"></RowDefinition>  
  6.   
  7.         <RowDefinition Height="*"></RowDefinition>  
  8.   
  9.     </Grid.RowDefinitions>  
  10.   
  11.     <Grid.ColumnDefinitions>  
  12.   
  13.         <ColumnDefinition Width="Auto"></ColumnDefinition>  
  14.   
  15.         <ColumnDefinition Width="*"></ColumnDefinition>  
  16.   
  17.     </Grid.ColumnDefinitions>  
  18.   
  19.   
  20.     <StackPanel>  
  21.   
  22.         <ListView Header="List of Employees" FontSize="30" Margin="30,100" x:Name="lstempDisplay" ItemsSource="{Binding}" Height="Auto">  
  23.   
  24.             <ListView.ItemTemplate>  
  25.   
  26.                 <DataTemplate x:Name="dataTemplate">  
  27.   
  28.                     <StackPanel>  
  29.   
  30.                         <TextBlock Text="{Binding EmployeeId}" Foreground="#FFFF" />  
  31.   
  32.                         <TextBlock Text="{Binding EmployeeName}" Foreground="#FFFF" />  
  33.   
  34.                         <TextBlock Text="{Binding Salary}" Foreground="#FFFF" />  
  35.   
  36.                         <TextBlock Text="{Binding Designation}" Foreground="#FFFF" />  
  37.   
  38.                         <TextBlock Text="{Binding PhoneNumber}" Foreground="#FFFF" />  
  39.   
  40.                     </StackPanel>  
  41.   
  42.                 </DataTemplate>  
  43.   
  44.             </ListView.ItemTemplate>  
  45.   
  46.         </ListView>  
  47.   
  48.     </StackPanel>  
  49. </Grid>  

Now run the application and see the output.
 

Step 4:

Now to get the information of each employee I added a combobox and the data is bound to the textboxes. If you want to edit you can edit and add a button to generate PDF.

  1. <StackPanel Margin="0,100">  
  2.   
  3. <ComboBox Header="Choose Employee Id" x:Name="cmbEmpId" SelectionChanged="cmbEmpId_Changed" ItemsSource="{Binding}" FontSize="25" HorizontalAlignment="Left" Width="231"  
  4.   
  5. SelectedItem="{Binding EmployeeId}" DisplayMemberPath="EmployeeId" SelectedValuePath="EmployeeId">  
  6.   
  7. <ComboBoxItem>Select</ComboBoxItem>  
  8.   
  9. </ComboBox>  
  10.   
  11. <TextBox x:Name="txtEmpName" Header="EmployeeName:" HorizontalAlignment="Left" FontSize="23" Width="231"/>  
  12.   
  13. <TextBox x:Name="txtSalary" Header="Salary:" HorizontalAlignment="Left" FontSize="23" Width="231"/>  
  14.   
  15. <TextBox x:Name="txtEmpDesignation" Header="Designation:" HorizontalAlignment="Left" FontSize="23" Width="231"/>  
  16.   
  17. <TextBox x:Name="txtPhoneNumber" Header="Designation:" HorizontalAlignment="Left" FontSize="23" Width="231"/>  
  18.   
  19. <Button HorizontalAlignment="Left" Click="GeneratePdf_Click" Margin="0,30" FontSize="23" Width="231" Content="Generate Pdf"/>  
  20.   
  21. </StackPanel>  

Step 5: Now to get the data into the textboxes I used selected Index changed event of combo box. Add the following code in MainPage.xaml.cs.

  1. private void cmbEmpId_Changed(object sender, SelectionChangedEventArgs e)  
  2.   {  
  3.       int EmployeeId = int.Parse(cmbEmpId.SelectedValue.ToString());  
  4.       Employee emp = _empModel.GetEmployeeById(EmployeeId);  
  5.       txtEmpName.Text = emp.EmployeeName;  
  6.       txtSalary.Text = emp.Salary;  
  7.       txtEmpDesignation.Text = emp.Designation;  
  8.       txtPhoneNumber.Text = emp.PhoneNumber;  
  9.   }  

Now run and select the Employee Id and observe the output.

Step 6: Now is the time to generate pdfthe PDF. Double click on "Generate Pdf" button and add the following code, this code has the reference from the following link: PostScript Language Reference

  1. private async void GeneratePdf_Click(object sender, RoutedEventArgs e)  
  2.         {  
  3.              
  4.             var file = await ApplicationData.Current.LocalFolder.CreateFileAsync("MyFirstPdf.pdf", Windows.Storage.CreationCollisionOption.ReplaceExisting);  
  5.             using (var stream = await System.IO.WindowsRuntimeStorageExtensions.OpenStreamForWriteAsync(file))  
  6.             {  
  7.                 using (var writer = new System.IO.StreamWriter(stream, System.Text.Encoding.UTF8))  
  8.                 {  
  9.   
  10.                     List<long> xrefs = new List<long>();  
  11.                     writer.WriteLine("%PDF-1.2");  
  12.                     writer.Write("%");  
  13.                     writer.Flush();  
  14.                     byte[] bytes = { 0, 0, 0, 0 };  
  15.                     stream.Write(bytes, 0, 4);  
  16.                     stream.Flush();  
  17.                     writer.WriteLine("");  
  18.   
  19.                     writer.Flush();  
  20.                     stream.Flush();  
  21.                     xrefs.Add(stream.Position);  
  22.                     writer.WriteLine("1 0 obj");  
  23.                     writer.WriteLine("<<");  
  24.                     writer.WriteLine("  /Type /Catalog");  
  25.                     writer.WriteLine("  /Pages 2 0 R");  
  26.                     writer.WriteLine(">>");  
  27.                     writer.WriteLine("endobj");  
  28.   
  29.                     // #2: page-list - we have only one child page  
  30.                     writer.Flush();  
  31.                     stream.Flush();  
  32.                     xrefs.Add(stream.Position);  
  33.                     writer.WriteLine("2 0 obj");  
  34.                     writer.WriteLine("<<");  
  35.                     writer.WriteLine("  /Type /Pages");  
  36.                     writer.WriteLine("  /Kids [3 0 R]");  
  37.                     writer.WriteLine("  /Count 1");  
  38.                     writer.WriteLine(">>");  
  39.                     writer.WriteLine("endobj");  
  40.   
  41.                     // #3: page - this is our page. We specify size, font resources, and the contents  
  42.                     writer.Flush();  
  43.                     stream.Flush();  
  44.                     xrefs.Add(stream.Position);  
  45.                     writer.WriteLine("3 0 obj");  
  46.                     writer.WriteLine("<<");  
  47.                     writer.WriteLine("  /Type /Page");  
  48.                     writer.WriteLine("  /Parent 2 0 R");  
  49.                     writer.WriteLine("  /MediaBox [0 0 612 792]");  
  50.                     // Default userspace units: 72/inch, origin at bottom left  
  51.                     writer.WriteLine("  /Resources");  
  52.                     writer.WriteLine("  <<");  
  53.                     writer.WriteLine("    /ProcSet [/PDF/Text]");  
  54.                     // This PDF uses only the Text ability  
  55.                     writer.WriteLine("    /Font");  
  56.                     writer.WriteLine("    <<");  
  57.                     writer.WriteLine("      /F0 4 0 R");  
  58.                     // I will define three fonts, #4, #5 and #6  
  59.                     writer.WriteLine("      /F1 5 0 R");  
  60.                     writer.WriteLine("      /F2 6 0 R");  
  61.                     writer.WriteLine("    >>");  
  62.                     writer.WriteLine("  >>");  
  63.                     writer.WriteLine("  /Contents 7 0 R");  
  64.                     writer.WriteLine(">>");  
  65.                     writer.WriteLine("endobj");  
  66.   
  67.                     // #4, #5, #6: three font resources, all using fonts that are built into all PDF-viewers  
  68.                     // We're going to use WinAnsi character encoding, defined below.  
  69.                     writer.Flush();  
  70.                     stream.Flush();  
  71.                     xrefs.Add(stream.Position);  
  72.                     writer.WriteLine("4 0 obj");  
  73.                     writer.WriteLine("<<");  
  74.                     writer.WriteLine("  /Type /Font");  
  75.                     writer.WriteLine("  /Subtype /Type1");  
  76.                     writer.WriteLine("  /Encoding /WinAnsiEncoding");  
  77.                     writer.WriteLine("  /BaseFont /Times-Roman");  
  78.                     writer.WriteLine(">>");  
  79.                     writer.Flush();  
  80.                     stream.Flush();  
  81.                     xrefs.Add(stream.Position);  
  82.                     writer.WriteLine("5 0 obj");  
  83.                     writer.WriteLine("<<");  
  84.                     writer.WriteLine("  /Type /Font");  
  85.                     writer.WriteLine("  /Subtype /Type1");  
  86.                     writer.WriteLine("  /Encoding /WinAnsiEncoding");  
  87.                     writer.WriteLine("  /BaseFont /Times-Bold");  
  88.                     writer.WriteLine(">>");  
  89.                     writer.Flush();  
  90.                     stream.Flush();  
  91.                     xrefs.Add(stream.Position);  
  92.                     writer.WriteLine("6 0 obj");  
  93.                     writer.WriteLine("<<");  
  94.                     writer.WriteLine("  /Type /Font");  
  95.                     writer.WriteLine("  /Subtype /Type1");  
  96.                     writer.WriteLine("  /Encoding /WinAnsiEncoding");  
  97.                     writer.WriteLine("  /BaseFont /Times-Italic");  
  98.                     writer.WriteLine(">>");  
  99.   
  100.                     // #7: contents of page. This is written in postscript, fully described in  
  101.                     // chapter 8 of the PDF 1.2 reference manual.  
  102.                     writer.Flush();  
  103.                     stream.Flush();  
  104.                     xrefs.Add(stream.Position);  
  105.                     System.Text.StringBuilder sb = new System.Text.StringBuilder();  
  106.                     sb.AppendLine("BT");  
  107.                     // BT = begin text object, with text-units the same as userspace-units  
  108.                     sb.AppendLine("/F0 30 Tf");  
  109.                     // Tf = start using the named font "F0" with size "30"  
  110.                     sb.AppendLine("30 TL");  
  111.                     // TL = set line height to "30"  
  112.                     sb.AppendLine("140.0 780.0 Td");  
  113.                     // Td = position text point at coordinates "140.0", "780.0"  
  114.                     sb.AppendLine("1.0 0.0 0.6 rg");  
  115.                     // rg = font foreground set to 1.0 0.0 0.6 for pink  
  116.                     sb.AppendLine("(Microsoft Corporation India) '");  
  117.                     sb.AppendLine("ET");  
  118.   
  119.                     //Border on pdf  
  120.                     //top  
  121.                     sb.AppendLine("BT");  
  122.                     sb.AppendLine("10 TL");  
  123.                     sb.AppendLine("50.0 730.0 Td");  
  124.                     sb.AppendLine("0.0 0.0 0.0 rg");  
  125.                     sb.AppendLine("(__________________________________)'");  
  126.                     sb.AppendLine("ET");  
  127.   
  128.                     //left  
  129.                     sb.AppendLine("BT");  
  130.                     sb.AppendLine("10 TL");  
  131.                     sb.AppendLine("47.0 703.0 Td");  
  132.                     sb.AppendLine("0.0 0.0 0.0 rg");  
  133.                     for (int i = 0; i <= 60; i++)  
  134.                     {  
  135.                         sb.AppendLine("(|)'");  
  136.                     }  
  137.                     sb.AppendLine("ET");  
  138.   
  139.                     //middle border  
  140.                     sb.AppendLine("BT");  
  141.                     sb.AppendLine("10 TL");  
  142.                     sb.AppendLine("240.0 703.0 Td");  
  143.                     sb.AppendLine("0.0 0.0 0.0 rg");  
  144.                     for (int i = 0; i <= 60; i++)  
  145.                     {  
  146.                         sb.AppendLine("(|)'");  
  147.                     }  
  148.                     sb.AppendLine("ET");  
  149.   
  150.                     //right end border  
  151.                     sb.AppendLine("BT");  
  152.                     sb.AppendLine("10 TL");  
  153.                     sb.AppendLine("557.0 703.0 Td");  
  154.                     sb.AppendLine("0.0 0.0 0.0 rg");  
  155.                     for (int i = 0; i <= 60; i++)  
  156.                     {  
  157.                         sb.AppendLine("(|)'");  
  158.                     }  
  159.                     sb.AppendLine("ET");  
  160.   
  161.                     //bottom border  
  162.                     sb.AppendLine("BT");  
  163.                     sb.AppendLine("10 TL");  
  164.                     sb.AppendLine("50.0 102.0 Td");  
  165.                     sb.AppendLine("0.0 0.0 0.0 rg");  
  166.                     sb.AppendLine("(__________________________________)'");  
  167.                     sb.AppendLine("ET");  
  168.   
  169.                     //Lables  
  170.                     sb.AppendLine("BT");  
  171.                     sb.AppendLine("/F0 15 Tf");  
  172.                     sb.AppendLine("20 TL");  
  173.                     sb.AppendLine("70.0 670.0 Td");  
  174.                     sb.AppendLine("0.0 0.2 1.0 rg");  
  175.                     sb.AppendLine("(EMPLOYEE ID)'");  
  176.                     sb.AppendLine("ET");  
  177.                     //  
  178.                     sb.AppendLine("BT");  
  179.                     sb.AppendLine("/F0 15 Tf");  
  180.                     sb.AppendLine("20 TL");  
  181.                     sb.AppendLine("0.0 0.0 0.0 rg");  
  182.                     sb.AppendLine("260.0 670.0 Td");  
  183.                     sb.AppendLine("(" + cmbEmpId.SelectedValue.ToString()+ ") '");  
  184.                     sb.AppendLine("ET");  
  185.                     //  
  186.                     sb.AppendLine("BT");  
  187.                     sb.AppendLine("/F0 15 Tf");  
  188.                     sb.AppendLine("20 TL");  
  189.                     sb.AppendLine("0.0 0.2 1.0 rg");  
  190.                     sb.AppendLine("70.0 645.0 Td");  
  191.                     sb.AppendLine("(EMPLOYEE NAME)'");  
  192.                     sb.AppendLine("ET");  
  193.                     //  
  194.                     sb.AppendLine("BT");  
  195.                     sb.AppendLine("/F0 15 Tf");  
  196.                     sb.AppendLine("20 TL");  
  197.                     sb.AppendLine("0.0 0.0 0.0 rg");  
  198.                     sb.AppendLine("260.0 645.0 Td");  
  199.                     sb.AppendLine("(" + txtEmpName.Text + ") '");  
  200.                     sb.AppendLine("ET");  
  201.                     //  
  202.                     sb.AppendLine("BT");  
  203.                     sb.AppendLine("/F0 15 Tf");  
  204.                     sb.AppendLine("20 TL");  
  205.                     sb.AppendLine("0.0 0.2 1.0 rg");  
  206.                     sb.AppendLine("70.0 615.0 Td");  
  207.                     sb.AppendLine("(EMPLOYEE SALARY)'");  
  208.                     sb.AppendLine("ET");  
  209.                     //  
  210.                     sb.AppendLine("BT");  
  211.                     sb.AppendLine("/F0 15 Tf");  
  212.                     sb.AppendLine("20 TL");  
  213.                     sb.AppendLine("260.0 615.0 Td");  
  214.                     sb.AppendLine("0.0 0.0 0.0 rg");  
  215.                     sb.AppendLine("(" + txtSalary.Text + ") '");  
  216.                     //  
  217.                     //  
  218.                     sb.AppendLine("BT");  
  219.                     sb.AppendLine("/F0 15 Tf");  
  220.                     sb.AppendLine("20 TL");  
  221.                     sb.AppendLine("0.0 0.2 1.0 rg");  
  222.                     sb.AppendLine("70.0 575.0 Td");  
  223.                     sb.AppendLine("(PHONENUMBER)'");  
  224.                     sb.AppendLine("ET");  
  225.                     //  
  226.                     sb.AppendLine("BT");  
  227.                     sb.AppendLine("/F0 15 Tf");  
  228.                     sb.AppendLine("20 TL");  
  229.                     sb.AppendLine("260.0 575.0 Td");  
  230.                     sb.AppendLine("0.0 0.0 0.0 rg");  
  231.                     sb.AppendLine("(" + txtPhoneNumber.Text + ") '");  
  232.                     sb.AppendLine("ET");  
  233.                     //  
  234.                     writer.WriteLine("7 0 obj");  
  235.                     writer.WriteLine("<<");  
  236.                     writer.WriteLine("  /Length " + sb.Length);  
  237.                     writer.WriteLine(">>");  
  238.                     writer.WriteLine("stream");  
  239.                     writer.Write(sb.ToString());  
  240.                     writer.WriteLine("  q");  //added  
  241.                     writer.WriteLine("    156 0 0 272 100 200 cm");  //[1 2 3 4 5 6 cm] translate to (5,6) and scale for 1  
  242.                     writer.WriteLine("    /Img1 Do");  
  243.                     writer.WriteLine("  Q");  
  244.                     writer.WriteLine("endstream");  
  245.                     writer.WriteLine("endobj");  
  246.   
  247.   
  248.                     writer.Flush();  
  249.                     stream.Flush();  
  250.                     dynamic xref_pos = stream.Position;  
  251.                     writer.WriteLine("xref");  
  252.                     writer.WriteLine("1 " + xrefs.Count);  
  253.                     long xref = 0;  
  254.                     foreach (long xref_loopVariable in xrefs)  
  255.                     {  
  256.                         xref = xref_loopVariable;  
  257.                         writer.WriteLine("{0:0000000000} {1:00000} n", xref, 0);  
  258.                     }  
  259.   
  260.                     // PDF-TRAILER. Every PDF ends with this trailer.  
  261.                     writer.WriteLine("trailer");  
  262.                     writer.WriteLine("<<");  
  263.                     writer.WriteLine("  /Size " + xrefs.Count);  
  264.                     writer.WriteLine("  /Root 1 0 R");  
  265.                     writer.WriteLine(">>");  
  266.                     writer.WriteLine("startxref");  
  267.                     writer.WriteLine(xref_pos);  
  268.                     writer.WriteLine("%%EOF");  
  269.                 }  
  270.             }  
  271.   
  272.             await Windows.System.Launcher.LaunchFileAsync(file);  
  273.         }  

Now click on the PDF and observe it. If you want to add borders add them easily by appending to string builder.

Here's the final output of pdf file.
 
 
 

 Thanks for reading my article. If you have any questions, then please mention in the comments section.