Analyzing your prompt, please hold on...
An error occurred while retrieving the results. Please refresh the page and try again.
There are a number of tasks when for some reason it is more convenient to export data from databases to a PDF document without using the recently popular HTML to PDF conversion scheme.
This article will show you how to generate a PDF document using the Aspose.PDF for .NET.
One of the most important classes in Aspose.PDF is a Document class. This class is a PDF rendering engine. To present a PDF structure, the Aspose.PDF library uses the Document-Page model, where:
Therefore, to create a PDF document with Aspose.PDF, you should follow these steps:
The most common problem is the output of data in a table format. The Table class is used to process tables. This class gives us the ability to create tables and place them in the document, using Rows and Cells. So, to create the table, you need to add the required number of rows and fill them with the appropriate number of cells.
The following example creates the table 4x10.
When initializing the Table object, the minimal skin settings were used:
As a result, we get the table 4x10 with equal-width columns.
The Table class provides methods for interacting with ADO.NET data sources - ImportDataTable and ImportDataView. The first method imports data from the DataTable, the second from the DataView. Premising that these objects are not very convenient for working in the MVC template, we will limit ourselves to a brief example. In this example (line 50), the ImportDataTable method is called and receives as parameters a DataTable instance and additional settings like the header flag and the initial position (rows/cols) for the data output.
More relevant for modern .NET is the import of data from ORM frameworks. In this case, it’s a good idea to extend the Table class with extension methods for importing data from a simple list or from the grouped data. Let’s give an example for one of the most popular ORMs - Entity Framework.
public static class PdfHelper
{
private static void ImportEntityList<TSource>(this Aspose.Pdf.Table table, IList<TSource> data)
{
var headRow = table.Rows.Add();
var props = typeof(TSource).GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach (var prop in props)
{
headRow.Cells.Add(prop.GetCustomAttribute(typeof(DisplayAttribute)) is DisplayAttribute dd ? dd.Name : prop.Name);
}
foreach (var item in data)
{
// Add row to table
var row = table.Rows.Add();
// Add table cells
foreach (var t in props)
{
var dataItem = t.GetValue(item, null);
if (t.GetCustomAttribute(typeof(DataTypeAttribute)) is DataTypeAttribute dataType)
switch (dataType.DataType)
{
case DataType.Currency:
row.Cells.Add(string.Format("{0:C}", dataItem));
break;
case DataType.Date:
var dateTime = (DateTime)dataItem;
if (t.GetCustomAttribute(typeof(DisplayFormatAttribute)) is DisplayFormatAttribute df)
{
row.Cells.Add(string.IsNullOrEmpty(df.DataFormatString)
? dateTime.ToShortDateString()
: string.Format(df.DataFormatString, dateTime));
}
break;
default:
row.Cells.Add(dataItem.ToString());
break;
}
else
{
row.Cells.Add(dataItem.ToString());
}
}
}
}
private static void ImportGroupedData<TKey, TValue>(this Aspose.Pdf.Table table, IEnumerable<Models.GroupViewModel<TKey, TValue>> groupedData)
{
var headRow = table.Rows.Add();
var props = typeof(TValue).GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach (var prop in props)
{
headRow.Cells.Add(prop.GetCustomAttribute(typeof(DisplayAttribute)) is DisplayAttribute dd ? dd.Name : prop.Name);
}
foreach (var group in groupedData)
{
// Add group row to table
var row = table.Rows.Add();
var cell = row.Cells.Add(group.Key.ToString());
cell.ColSpan = props.Length;
cell.BackgroundColor = Aspose.Pdf.Color.DarkGray;
cell.DefaultCellTextState.ForegroundColor = Aspose.Pdf.Color.White;
foreach (var item in group.Values)
{
// Add data row to table
var dataRow = table.Rows.Add();
// Add cells
foreach (var t in props)
{
var dataItem = t.GetValue(item, null);
if (t.GetCustomAttribute(typeof(DataTypeAttribute)) is DataTypeAttribute dataType)
switch (dataType.DataType)
{
case DataType.Currency:
dataRow.Cells.Add(string.Format("{0:C}", dataItem));
break;
case DataType.Date:
var dateTime = (DateTime)dataItem;
if (t.GetCustomAttribute(typeof(DisplayFormatAttribute)) is DisplayFormatAttribute df)
{
dataRow.Cells.Add(string.IsNullOrEmpty(df.DataFormatString)
? dateTime.ToShortDateString()
: string.Format(df.DataFormatString, dateTime));
}
break;
default:
dataRow.Cells.Add(dataItem.ToString());
break;
}
else
{
dataRow.Cells.Add(dataItem.ToString());
}
}
}
}
}
}
The Data Annotations attributes are often used to describe models and help us to create the table. Therefore, the following table generation algorithm was chosen for ImportEntityList:
In this example, additional customizations were made for DataType.Currency (lines 32-34) and DataType.Date (lines 35-43), but you can add others if necessary. The algorithm of the ImportGroupedData method is almost the same as the previous one. An additional GroupViewModel class is used, to store the grouped data.
using System.Collections.Generic;
public class GroupViewModel<K,T>
{
public K Key;
public IEnumerable<T> Values;
}
Since we process groups, first we generate a line for the key value (lines 66-71), and after it - the lines of this group.
Analyzing your prompt, please hold on...
An error occurred while retrieving the results. Please refresh the page and try again.