Чтобы экспортировать лист Excel в PDF из Delphi или C++Builder без установки MS Office, вызовите метод SaveAsPDF для листа или книги HotXLS. HotXLS — это нативный VCL-компонент Excel. Экспорт листа в PDF преобразует используемый диапазон листа в файл PDF 1.4, сопоставляя ширину столбцов Excel и отображаемый текст ячеек с страницами формата A4 с автоматической разбивкой на страницы. В процессе рендеринга не участвуют установленный Excel, драйверы принтера или сторонние DLL
HotXLS рассматривает PDF как формат представления данных, аналогичный его путям экспорта в CSV, TSV и HTML, а не как систему рендеринга с попиксельной точностью. Экспорт воспроизводит табличный контент и макет: значения в сетке, пропорции столбцов и сетку ячеек. Это понимание важно, так как оно задает правильные ожидания, а далее мы разберем границы возможностей
Как конвертировать Excel в PDF в Delphi без Office?
Кратчайший путь — один вызов. Класс TXLSWorksheet предоставляет методы SaveAsPDF(FileName) и SaveAsPDF(Stream), а класс TXLSWorkbook предоставляет те же две перегрузки, которые перенаправляют вызов на активный лист. Каждый метод возвращает Integer: значение 1 при успехе и -1 при сбое, что позволяет обрабатывать результат без оборачивания вызова в обработку исключений
uses
lxHandle;
var
Book: TXLSWorkbook;
begin
Book := TXLSWorkbook.Create;
try
Book.Open('sales-june.xlsx');
// Render the active sheet's used range straight to report.pdf.
if Book.SaveAsPDF('report.pdf') = 1 then
Writeln('PDF written');
finally
Book.Free;
end;
end;
При вызове SaveAsPDF для листа HotXLS экспортирует его область UsedRange — габариты всех заполненных ячеек. Перегрузка книги делегирует задачу активному листу, поэтому для многостраничного отчета вам нужно либо обойти листы в цикле, либо предварительно выбрать активный лист. В библиотеке нет режима «все в один проход» для экспорта всей книги целиком: каждый вызов преобразует ровно один лист или один диапазон
Как HotXLS преобразует используемый диапазон в страницы PDF?
HotXLS обходит заполненный диапазон ячейка за ячейкой и размещает их в виде постраничной сетки. Геометрия столбцов берется непосредственно из Excel: ширина каждого столбца преобразуется из единиц ширины Excel в типографские пункты с ограничением по минимальной ширине, чтобы столбцы не схлопывались. Если суммарная ширина столбцов превышает печатную область страницы, HotXLS пропорционально масштабирует их для укладки на лист; если они умещаются свободно, они сохраняют свои физические размеры без растяжения
Строки переносятся на новые страницы при пересечении нижней границы печатной области, поэтому лист из тысячи строк разбивается на страницы автоматически без вашего участия. Каждая ячейка выводит свое значение FormattedText — отображаемую строку после применения формата чисел (даты отображаются как на листе, денежные значения сохраняют разделители тысяч и символы валют). Текст, выходящий за границы столбца, обрезается по ширине ячейки и не перетекает на соседние
Настройка ориентации, полей и размера шрифта
Для настройки макета вы можете управлять экспортером напрямую. Класс TXLSPDFExport лежит в основе простых методов и содержит три ключевых свойства: Orientation (xlsPdfPortrait или xlsPdfLandscape, по умолчанию книжная), Margin (в пунктах, по умолчанию 40) и FontSize (в пунктах, по умолчанию 9). Задайте их перед вызовом SaveAsPDF, и они применятся к документу
uses
lxHandle, lxPDF;
var
Book: TXLSWorkbook;
Exporter: TXLSPDFExport;
begin
Book := TXLSWorkbook.Create;
try
Book.Open('wide-ledger.xlsx');
Exporter := TXLSPDFExport.Create;
try
Exporter.Orientation := xlsPdfLandscape; // fit wide sheets on the page
Exporter.Margin := 28; // tighter page margin, in points
Exporter.FontSize := 8; // denser rows
Exporter.SaveAsPDF(Book.ActiveSheet, 'ledger.pdf');
finally
Exporter.Free;
end;
finally
Book.Free;
end;
end;
Класс TXLSPDFExport также принимает диапазон вместо листа через метод SaveAsPDF(Range: IXLSRange; ...), что позволяет экспортировать только итоговую таблицу с листа, содержащего также промежуточные расчеты. Этот метод используется листом на внутреннем уровне, поэтому логика макета, масштабирования и разбивки на страницы работает одинаково для всего листа и для выбранного диапазона
var
Book: TXLSWorkbook;
Exporter: TXLSPDFExport;
Summary: IXLSRange;
begin
Book := TXLSWorkbook.Create;
try
Book.Open('quarter.xlsx');
// Export only the summary block, not the scratch columns beside it.
Summary := Book.Sheets[1].Range['A1', 'F20'];
Exporter := TXLSPDFExport.Create;
try
Exporter.SaveAsPDF(Summary, 'summary.pdf');
finally
Exporter.Free;
end;
finally
Book.Free;
end;
end;
Почему HotXLS не внедряет шрифты: особенности Helvetica и WinAnsi
HotXLS записывает текст со встроенным шрифтом Helvetica и кодировкой WinAnsiEncoding. Это осознанный выбор для обеспечения нулевой зависимости с одним важным ограничением. Поскольку Helvetica является одним из 14 стандартных шрифтов, которые по умолчанию поддерживает любое совместимое средство просмотра PDF, экспортер вообще не внедряет файлы шрифтов в документ. Благодаря этому файлы имеют минимальный размер и открываются везде без необходимости лицензировать или поставлять файлы шрифтов. Платой за это решение является набор символов, которые могут отображаться на странице
Кодировка WinAnsiEncoding покрывает набор Windows-1252, поэтому латиница, стандартные знаки препинания и западноевропейские диакритические знаки выводятся корректно. HotXLS также поддерживает спецсимволы, кавычки, длинные тире и знак евро в их позициях CP1252. Символы за пределами этого диапазона (кириллица, греческий, арабский, иероглифы) преобразуются в знаки вопроса. Если ваши таблицы содержат нелатинский текст, данный экспортер не подойдет, и вам потребуется полноценная система рендеринга PDF с поддержкой шрифтов
Ограничения экспорта листов в PDF
HotXLS преобразует содержимое и структуру, а не визуальный стиль оформления листа. Заливка ячеек, стили рамок, шрифты и цвета отдельных ячеек, диаграммы и встроенные изображения не отображаются при экспорте. На выходе вы получите текстовую сетку со стандартными линиями ячеек. Те же правила действуют для экспортеров в HTML и RTF, и этого достаточно для отчетов или выгрузок данных, где важны сами числа, а не их оформление
Если вам требуется документ в строгом соответствии с корпоративным стилем, обычным решением является подготовка данных в шаблоне, что подробно рассматривается в статье о генерации отчетов на основе шаблонов. И поскольку этот процесс не использует COM или запущенный Excel, решение соответствует общей модели автоматизации без MS Office, применяемой в HotXLS: чистый код на Pascal, развертываемый на сервере без необходимости лицензирования
Файл PDF байт за байтом
HotXLS формирует структуру PDF-файла вручную и рассчитывает таблицу перекрестных ссылок по точным байтовым смещениям, благодаря чему файл открывается в любых средствах чтения. При сериализации каждого объекта HotXLS записывает его начальное смещение перед добавлением байтов, а затем сдвигает текущую позицию на записанную длину, так что таблица xref точно указывает на каждый объект, а startxref отмечает начало таблицы. Просмотрщик, обнаружив расхождение в смещении хотя бы на один байт, отклонит весь файл, поэтому автоматический расчет смещений является критически важной частью работы экспортера
Этот принцип накладывает строгое условие. Узел страниц (Pages node) записывается первым как объект 1, но его список дочерних страниц становится известен только после генерации всех страниц, поэтому HotXLS резервирует его как заглушку и прописывает итоговые страницы и их количество перед расчетом смещений, но не после него. После того как байты объекта измерены для xref, они фиксируются: изменение любого байта после этого сдвинет последующие смещения и повредит таблицу. Это небольшое структурное правило позволяет получать стандартизированные файлы PDF 1.4 без использования сторонних библиотек
Описанные здесь методы SaveAsPDF и класс TXLSPDFExport поставляются в составе компонента HotXLS для Delphi и C++Builder вместе с экспортерами в CSV, HTML и RTF, а также полным API работы с листами