尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
C++ PDF PoDoFo库使用教程
#include podofo/podofo.h #include iostream // All PoDoFo classes are member of the PoDoFo namespace. //using namespace std; using namespace PoDoFo; PdfFont* getFont(PdfDocument doc); // Base14 other non-Base14 fonts for comparison static const char* s_base14fonts[] { Times-Roman, Times-Italic, Times-Bold, Times-BoldItalic, Helvetica, Helvetica-Oblique, Helvetica-Bold, Helvetica-BoldOblique, Courier, Courier-Oblique, Courier-Bold, Courier-BoldOblique, Symbol, ZapfDingbats, Arial, Verdana }; const char* GetBase14FontName(unsigned i) { if (i std::size(s_base14fonts)) return nullptr; return s_base14fonts[i]; } void DrawRedFrame(PdfPainter painter, double x, double y, double width, double height) { // draw red box painter.GraphicsState.SetFillColor(PdfColor(1.0f, 0.0f, 0.0f)); painter.GraphicsState.SetStrokeColor(PdfColor(1.0f, 0.0f, 0.0f)); painter.DrawLine(x, y, x width, y); if (height 0.0f) { painter.DrawLine(x, y, x, y height); painter.DrawLine(x width, y, x width, y height); painter.DrawLine(x, y height, x width, y height); } // restore to black painter.GraphicsState.SetFillColor(PdfColor(0.0f, 0.0f, 0.0f)); painter.GraphicsState.SetStrokeColor(PdfColor(0.0f, 0.0f, 0.0f)); } void DemoBase14Fonts(PdfPainter painter, PdfPage page, PdfDocument document) { PdfFontSearchParams params; params.AutoSelect PdfFontAutoSelectBehavior::Standard14; double x 56, y page.GetRect().Height - 56.69; std::string_view demo_text abcdefgABCDEFG12345!#$%-? ; double height 0.0f, width 0.0f; // draw sample of all types for (unsigned i 0; i std::size(s_base14fonts); i) { x 56; y y - 25; std::string text; if (i 12) { // Or u8♠♣♥♦: Symbol font doesnt support regular characters text u8\\u2660\\u2663\\u2665\\u2666; } else if (i 13) { // Or u8❏❑▲▼: ZapfDingbats font doesnt support regular characters text u8\\u274f\\u2751\\u25b2\\u25bc; } else { text demo_text; text.append(GetBase14FontName(i)); } PdfFont* font document.GetFonts().SearchFont(GetBase14FontName(i), params); font document.GetFonts().GetStandard14Font(PdfStandard14FontType::Helvetica); font getFont(document); if (font nullptr) throw std::runtime_error(Font not found); painter.TextState.SetFont(*font, 12.0); width font-GetStringLength(text, painter.TextState); height font-GetLineSpacing(painter.TextState); std::cout GetBase14FontName(i) Width width Height height std::endl; // draw red box DrawRedFrame(painter, x, y, width, height); // draw text painter.DrawText(text, x, y); } // draw some individual characters: std::string_view demo_text2 _1jiPlg .;; auto helveticaStd14 document.GetFonts().SearchFont(Helvetica, params); auto arialImported document.GetFonts().SearchFont(Arial); helveticaStd14 getFont(document); arialImported getFont(document); auto metrics arialImported-GetMetrics(); std::cout Non base 14 font characteristics std::endl; std::cout Font name: metrics.GetFontName() std::endl; std::cout Family font name: metrics.GetFontFamilyName() std::endl; std::cout Font file path: metrics.GetFilePath() std::endl; std::cout Font face index: metrics.GetFaceIndex() std::endl; // draw individuals for (unsigned i 0; i demo_text2.length(); i) { x 56; y y - 25; std::string text; if (i 0) text Helvetica / Arial Comparison:; else text (std::string)demo_text2.substr(i, 1); painter.TextState.SetFont(*helveticaStd14, 12); height helveticaStd14-GetLineSpacing(painter.TextState); width helveticaStd14-GetStringLength(text, painter.TextState); // draw red box DrawRedFrame(painter, x, y, width, height); // draw text painter.DrawText(text, x, y); if (i 0) { // draw again, with non-Base14 font painter.TextState.SetFont(*arialImported, 12); height arialImported-GetLineSpacing(painter.TextState); width arialImported-GetStringLength((std::string_view)text, painter.TextState); // draw red box DrawRedFrame(painter, x 100, y, width, height); // draw text painter.DrawText(text, x 100, y); } } } void drawSquareWithCross(PdfPainter painter, double x, double y) { painter.Save(); const double SquareSize 6; painter.GraphicsState.SetLineWidth(0.6); painter.DrawRectangle(x - SquareSize / 2, y - SquareSize / 2, SquareSize, SquareSize); painter.GraphicsState.SetLineWidth(0); painter.DrawLine(x, y - SquareSize / 2, x, y SquareSize / 2); painter.DrawLine(x - SquareSize / 2, y, x SquareSize / 2, y); painter.Restore(); } void createDocument2(const char* filename) { PdfMemDocument doc; auto page doc.GetPages().CreatePage(PdfPage::CreateStandardPageSize(PdfPageSize::A4)); PdfFontCreateParams params; params.Encoding PdfEncodingMapFactory::WinAnsiEncodingInstance(); auto font doc.GetFonts().GetStandard14Font(PdfStandard14FontType::Helvetica, params); PdfPainter painter; auto operators static_castPdfContentStreamOperators(painter); painter.SetCanvas(page); painter.TextState.SetFont(font, 15); painter.TextObject.Begin(); painter.TextObject.MoveTo(100, 500); painter.TextObject.AddText(Test1); // Some low level operations operators.TJ_Operator_Begin(); operators.TJ_Operator_Glyphs(_W, false); operators.TJ_Operator_Delta(-500); operators.TJ_Operator_Glyphs(orld, false); operators.TJ_Operator_End(); painter.TextObject.End(); painter.DrawText(Test2, 100, 600, PdfDrawTextStyle::StrikeThrough); PdfPainterPath path; path.MoveTo(20, 20); path.AddArcTo(150, 20, 150, 70, 50); path.AddLineTo(150, 120); path.AddArc(200, 120, 50, 3.14159, 3.14159 / 8, true); auto currPoint1 path.GetCurrentPoint(); PdfPainterPath path2; path2.MoveTo(250, 120); path2.AddLineTo(250, 80); path.AddPath(path2, true); auto currPoint2 path.GetCurrentPoint(); painter.DrawPath(path, PdfPathDrawMode::Stroke); path.Reset(); path.MoveTo(40, 40); path.AddLineTo(100, 40); path.AddLineTo(70, 80); path.AddLineTo(40, 40); path.AddCircle(200, 300, 60); painter.DrawPath(path, PdfPathDrawMode::Fill); drawSquareWithCross(painter, 100, 20); drawSquareWithCross(painter, 100, 70); drawSquareWithCross(painter, 150, 70); drawSquareWithCross(painter, currPoint1.X, currPoint1.Y); drawSquareWithCross(painter, currPoint2.X, currPoint2.Y); painter.FinishDrawing(); doc.Save(filename); } // 创建一个PDF文件 void testCreatePDF(const char* filename) { PdfMemDocument document; PdfPainter painter; PdfFont* font; try { auto page document.GetPages().CreatePage(PdfPage::CreateStandardPageSize(PdfPageSize::A4)); painter.SetCanvas(page); font document.GetFonts().SearchFont(Microsoft YaHei); //font document.GetFonts().GetStandard14Font(PdfStandard14FontType::Helvetica); font getFont(document); if (font nullptr) throw std::runtime_error(Invalid handle); auto metrics font-GetMetrics(); std::cout The font name is metrics.GetFontName() std::endl; std::cout The family font name is metrics.GetFontFamilyName() std::endl; std::cout The font file path is metrics.GetFilePath() std::endl; std::cout The font face index is metrics.GetFaceIndex() std::endl; painter.TextState.SetFont(*font, 18); // painter.SetColor(1.0, 0.0, 0.0); painter.DrawText(ABCDEFGHIKLMNOPQRSTVXYZ, 56.69, page.GetRect().Height - 56.69); try { // Add also some non-ASCII characters (Cyrillic alphabet) painter.DrawText(АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЬЫЭЮЯ, 56.69, page.GetRect().Height - 80); } catch (PdfError err) { if (err.GetCode() PdfErrorCode::InvalidFontData) std::cout WARNING: The matched font metrics.GetFontName() doesnt support cyrillic std::endl; } //DemoBase14Fonts(painter, page, document); painter.FinishDrawing(); // Set some additional information on the PDF file. document.GetMetadata().SetCreator(PdfString(examplahelloworld - A PoDoFo test application)); document.GetMetadata().SetAuthor(PdfString(Dominik Seichter)); document.GetMetadata().SetTitle(PdfString(Hello World)); document.GetMetadata().SetSubject(PdfString(Testing the PoDoFo PDF Library)); document.GetMetadata().SetKeywords(std::vectorstd::string({ Test, PDF, Hello World })); // The last step is to close the document. document.Save(filename); } catch (PdfError e) { // All PoDoFo methods may throw exceptions // make sure that painter.FinishPage() is called // or who will get an assert in its destructor try { painter.FinishDrawing(); } catch (...) { // Ignore errors this time } throw e; } } #include windows.h HFONT createWinFont() { return CreateFont( -15/*高度*/, -7.5/*宽度*/, 0/*不用管*/, 0/*不用管*/, 400 /*一般这个值设为400*/, FALSE/*不带斜体*/, FALSE/*不带下划线*/, FALSE/*不带删除线*/, DEFAULT_CHARSET, //这里我们使用默认字符集还有其他以 _CHARSET 结尾的常量可用 OUT_CHARACTER_PRECIS, CLIP_CHARACTER_PRECIS, //这行参数不用管 DEFAULT_QUALITY, //默认输出质量 FF_DONTCARE, //不指定字体族*/ 微软雅黑 //字体名 ); } PdfFont* getFont(PdfDocument doc) { return doc.GetFonts().GetOrCreateFont(createWinFont()); } void testFonts() { } void test() { //auto fc GetFontConfigWrapper(); //fc.AddFontDirectory(C://fonts); //PdfCommon::AddFontDirectory(C:\\Users\\ws\Downloads\\podofo\\extern\\resources\\Fonts\\); PdfCommon::SetMaxLoggingSeverity(PdfLogSeverity::Warning); testCreatePDF(./test.pdf); createDocument2(./test2.pdf); }输出/*The font name is MicrosoftYaHeiThe family font name is Microsoft YaHeiThe font file path isThe font face index is 0*/参考GitHub - podofo/podofo: A C17 PDF manipulation libraryC pdf库总结-CSDN博客C PDF转图片-CSDN博客创作不易小小的支持一下吧
RELATED

相关推荐

快速重装系统

快速重装系统

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📅 2026/11/2 1:12:16
C++自定义可对称双向迭代器

C++自定义可对称双向迭代器

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📅 2026/11/2 1:12:16
C++ 列式内存布局数据存储格式 Arrow

C++ 列式内存布局数据存储格式 Arrow

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📅 2026/11/2 1:12:16
MORE NEWS

更多资讯

📰

c++实现的常见缓存算法和LRU

前言 缓存的核心矛盾是容量有限而数据无限:当新的键值对要进来而缓存已满时,必须挑一个旧条目淘汰。挑谁,就是缓存淘汰算法要回答的问题。FIFO 按进入时间淘汰,LRU 按最近使用时间淘汰,LFU 按使用频率淘汰,…

📰

OpenCV颜色识别实战:HSV空间与inRange阈值调参指南

简介:这份资源面向具备一定C#基础、希望在桌面端实现图像颜色识别的开发者,围绕OpenCV的C#封装OpenCvSharp展开,重点讲解HSV颜色空间下的颜色筛选与掩码处理,可用于自动化检测、机器人视觉、物体定位等场景的入门与练手。压缩包共…

📰

气象数据分析实战:从数据清洗到趋势检验的完整实验流程

简介:这份资源面向数据分析初学者与需要完成课程实验的学生,围绕气象数据展开完整分析实践:通过爬虫代码抓取中国天气网某一城市的天气数据,再对数据做清洗与统计,生成雷达图、条形图等多种可视化图表,并配…

📰

Windows下UDP组播收发程序实战:从原理到避坑指南

简介:面向Windows平台网络编程初学者与需要实现多播通信的开发者,这份资源提供了一套可直接编译运行的UDP组播发送与接收示例工程。内容围绕Winsock编程展开,涵盖组播地址与端口设置、套接字创建绑定、通过IP_ADD_MEMBERSHIP加入多播组&#…

📰

开源备忘:我做了个在线 3D 寺庙 sansatemple.live(赛博산사)

做了一件偏「氛围」的小东西:赛博산사 / Cyber Sansa。 正式地址只认这个: https://sansatemple.live 浏览器打开就是一座可逛的 3D 寺庙:多间殿堂、可与其他访客同在(presence 有人数上限,避免房间卡死)&a…

📰

Spring Cloud Alibaba分布式商城复现:中间件、检索与下单事务

简介:围绕谷粒商城微服务分布式电商项目整理的高级篇代码与配套材料,面向具备Java后端基础、希望系统理解电商平台落地方式的开发者,重点解决微服务拆分、服务治理与高可用架构等学习诉求。内容围绕用户、商品、订单、支付等服务展开&#xf…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬