使用libharu和PoDoFo在C++中生成PDF报告
在现代C++开发中,经常需要以编程方式创建PDF格式文档:从简单的文本报告到包含表格、图表和图像的复杂多页文档。本文将详细介绍两个流行的C++ PDF生成库——libharu和PoDoFo,并提供实际使用示例。
1. libharu库
libharu是一个轻量级、跨平台的C语言PDF文件创建库。它不依赖外部库(除了用于压缩的zlib),支持Unicode、字体嵌入、图像(JPEG/PNG)以及基本矢量图元。非常适合生成简单的报告、发票、证明文件。
安装(Linux / Windows)
- Linux (Ubuntu/Debian):
sudo apt-get install libhpdf-dev - Windows (vcpkg):
vcpkg install libharu - Windows (从源码编译): 从GitHub下载压缩包,通过CMake编译。
示例:创建包含文本和线条的简单PDF
#include <hpdf.h>#include <stdio.h>
int main() { HPDF_Doc pdf = HPDF_New(NULL, NULL); if (!pdf) { fprintf(stderr, "创建文档失败"); return 1; }
HPDF_Page page = HPDF_AddPage(pdf); HPDF_Page_SetSize(page, HPDF_PAGE_SIZE_A4, HPDF_PAGE_PORTRAIT);
// 标题 HPDF_Page_BeginText(page); HPDF_Page_SetFontAndSize(page, HPDF_GetFont(pdf, "Helvetica", NULL), 24); HPDF_Page_TextOut(page, 50, 750, "第一季度销售报告"); HPDF_Page_EndText(page);
// 标题下方的线条 HPDF_Page_SetLineWidth(page, 1.5); HPDF_Page_MoveTo(page, 50, 735); HPDF_Page_LineTo(page, 545, 735); HPDF_Page_Stroke(page);
// 保存 HPDF_SaveToFile(pdf, "report.pdf"); HPDF_Free(pdf); printf("PDF已创建: report.pdf"); return 0;}示例:添加表格(模拟)
libharu没有内置的表格模块,但可以手动绘制表格:
void draw_table(HPDF_Page page, float x, float y, float col_width, float row_height, int rows, int cols) { for (int r = 0; r <= rows; ++r) { HPDF_Page_MoveTo(page, x, y - r * row_height); HPDF_Page_LineTo(page, x + cols * col_width, y - r * row_height); HPDF_Page_Stroke(page); } for (int c = 0; c <= cols; ++c) { HPDF_Page_MoveTo(page, x + c * col_width, y); HPDF_Page_LineTo(page, x + c * col_width, y - rows * row_height); HPDF_Page_Stroke(page); }}2. PoDoFo库
PoDoFo是一个更现代、更强大的C++库,支持C++17。它提供面向对象的API,支持表单、注释、书签、TrueType/OpenType字体嵌入,以及读取和编辑现有PDF。PoDoFo更适合包含动态内容的复杂报告。
安装
- Linux:
sudo apt-get install libpodofo-dev(版本可能较旧,建议从源码编译) - Windows: 通过vcpkg:
vcpkg install podofo - 从源码编译:需要CMake、zlib、libpng、freetype、fontconfig。
示例:创建包含表格和图像的PDF
#include <podofo/podofo.h>#include <iostream>
int main() { using namespace PoDoFo;
PdfMemDocument doc; PdfPage* page = doc.CreatePage(PdfPage::CreateStandardPageSize(PdfPageSize::A4)); PdfPainter painter; painter.SetCanvas(*page);
// 字体 auto