Analyzing your prompt, please hold on...
An error occurred while retrieving the results. Please refresh the page and try again.
Существует ряд задач, когда по какой-то причине удобнее экспортировать данные из баз данных в PDF-документ без использования недавно популярной схемы конвертации HTML в PDF.
Эта статья покажет вам, как создать PDF-документ с использованием Aspose.PDF for .NET.
Одним из самых важных классов в Aspose.PDF является класс Document. Этот класс является движком рендеринга PDF. Для представления структуры PDF библиотека Aspose.PDF использует модель Document-Page, где:
Поэтому, чтобы создать PDF-документ с Aspose.PDF, вам следует выполнить следующие шаги:
Наиболее распространенной проблемой является вывод данных в табличном формате. Для обработки таблиц используется класс Table. Этот класс дает нам возможность создавать таблицы и размещать их в документе, используя Rows и Cells. Таким образом, чтобы создать таблицу, вам нужно добавить необходимое количество строк и заполнить их соответствующим количеством ячеек.
Следующий пример создает таблицу 4x10.
При инициализации объекта Table использовались минимальные настройки оформления:
В результате мы получаем таблицу 4x10 с равными по ширине столбцами.
Класс Table предоставляет методы для взаимодействия с источниками данных ADO.NET - ImportDataTable и ImportDataView. Первый метод импортирует данные из DataTable, второй - из DataView. Предполагая, что эти объекты не очень удобны для работы в шаблоне MVC, мы ограничимся кратким примером. В этом примере (строка 50) вызывается метод ImportDataTable и получает в качестве параметров экземпляр DataTable и дополнительные настройки, такие как флаг заголовка и начальная позиция (строки/столбцы) для вывода данных.
Более актуальным для современного .NET является импорт данных из ORM-фреймворков. В этом случае разумно расширить класс Table методами расширения для импорта данных из простого списка или из сгруппированных данных. Приведем пример для одного из самых популярных ORM - 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());
}
}
}
}
}
}
Атрибуты Data Annotations часто используются для описания моделей и помогают нам создавать таблицу. Поэтому для метода ImportEntityList был выбран следующий алгоритм генерации таблицы:
В этом примере были сделаны дополнительные настройки для DataType.Currency (строки 32-34) и DataType.Date (строки 35-43), но вы можете добавить другие при необходимости. Алгоритм метода ImportGroupedData почти такой же, как и предыдущий. Используется дополнительный класс GroupViewModel для хранения сгруппированных данных.
using System.Collections.Generic;
public class GroupViewModel<K,T>
{
public K Key;
public IEnumerable<T> Values;
}
Поскольку мы обрабатываем группы, сначала мы генерируем строку для ключевого значения (строки 66-71), а затем - строки этой группы.
Analyzing your prompt, please hold on...
An error occurred while retrieving the results. Please refresh the page and try again.