1.简介
DocxFactory 是一个专注于处理 Microsoft Word 文档(.docx 格式)的 C++ 库,主要用于动态创建、修改和生成 docx 文档,尤其擅长基于模板批量生成结构化文档。
DocxFactory 是一个用于处理 Microsoft Word 文档的 C++ 开源库,支持基于模板批量生成结构化文档。它通过占位符替换文本、动态生成表格及插入图片,无需依赖 Office 控件。文章介绍了环境搭建、依赖配置(如 libxml2)、模板设计技巧(占位符、书签、重复块)以及常用场景示例(文本替换、表格生成、图片插入)。此外还涵盖了高级功能(条件判断、样式控制)及常见问题解决方案,适合高性能服务器端文档生成场景。

DocxFactory 是一个专注于处理 Microsoft Word 文档(.docx 格式)的 C++ 库,主要用于动态创建、修改和生成 docx 文档,尤其擅长基于模板批量生成结构化文档。
DocxFactory 的设计目标是简化 C++ 程序对 docx 文档的操作,通过'模板 + 数据填充'的模式,高效生成符合格式要求的 Word 文档。由于 docx 本质是 XML 格式的压缩包,该库底层基于 XML 解析和处理实现,但屏蔽了复杂的 XML 细节,提供了更直观的 API。
它的主要功能有:
${variable}),通过代码将动态数据(文本、数字、表格等)替换到占位符位置,实现批量文档生成(如合同、报表、证书等)。它的特点有:
libxml2(Linux/macOS)或通过 NuGet 安装(Windows)。Windows(Visual Studio):
include)添加到项目属性 > C/C++ > 常规 > 附加包含目录。lib)添加到链接器 > 常规 > 附加库目录,并在链接器 > 输入 > 附加依赖项中添加 docxfactory.lib。Linux/macOS(GCC):
// 安装依赖
sudo apt-get install libxml2-dev # Linux
brew install libxml2 # macOS
// 编译示例代码
g++ -std=c++11 -Iinclude -Llib -ldocxfactory your_code.cpp -o output
编译并运行,若输出版本号则安装成功。
创建一个简单的测试文件 test.cpp:
#include <DocxFactory/DocxFactory.h>
#include <iostream>
using namespace DocxFactory;
int main() {
Initialize::init();
std::cout << "DocxFactory 版本:" << Version::getVersion() << std::endl;
Initialize::uninit();
return 0;
}
编译并运行,若输出版本号则安装成功。
在 Word 模板中使用 ${变量名} 定义动态内容:
尊敬的 ${userName},您好!合同日期:${contractDate,yyyy-MM-dd}(支持自定义格式)。salesRow)。${product.name} ${product.price})。${logo} 作为占位符名称。以下是 DocxFactory 最常用的 3 类核心场景示例,涵盖从简单文本替换到复杂表格、图片插入,代码均包含关键步骤注释,可直接参考适配。所有示例需先确保项目已正确链接 DocxFactory 库和依赖(如 libxml2)。
用途:批量生成带动态文本的文档(如合同、通知中的姓名、日期、金额)
前提:需先在 docx 模板中定义占位符,格式为 ${占位符名}(如模板中写 ${userName} ${contractDate})。
#include <DocxFactory/DocxFactory.h>
#include <memory> // 用于智能指针管理资源
using namespace DocxFactory;
using namespace std;
int main() {
try {
// 1. 初始化 DocxFactory 库
Initialize::init();
// 2. 加载 docx 模板(替换为你的模板路径)
auto_ptr<Template> docTemplate(Template::load("template_contract.docx"));
// 3. 获取模板的'数据替换上下文',用于填充占位符
auto_ptr<Context> context(docTemplate->getContext());
// 4. 替换模板中的占位符(key 对应模板中的 ${key},value 为替换内容)
context->replace("userName", "张三"); // 文本替换
context->replace("contractDate", "2025-10-29"); // 日期替换
context->replace("contractAmount", "50000.00"); // 数字替换
// 5. 生成最终文档(替换为你的输出路径)
docTemplate->generate("output_contract_张三.docx");
// 6. 清理资源(智能指针自动释放,也可手动 delete)
Initialize::uninit();
cout << "文档生成成功!" << endl;
} catch (const Exception& e) {
// 捕获库抛出的异常(如模板不存在、占位符未找到)
cerr << "错误:" << e.what() << endl;
return 1;
}
return 0;
}
用途:生成带批量数据的表格(如销售报表、员工名单)
前提:模板中需先插入一个表格,并在表格行的单元格中定义'重复占位符'(如 ${tableData.name} ${tableData.sales}),表示这一行需要循环生成。
#include <DocxFactory/DocxFactory.h>
#include <vector>
#include <memory>
using namespace DocxFactory;
using namespace std;
// 定义表格数据结构(与模板占位符对应)
struct SalesData {
string name; // 对应模板 ${tableData.name}
string sales; // 对应模板 ${tableData.sales}
};
int main() {
try {
Initialize::init();
auto_ptr<Template> docTemplate(Template::load("template_sales.docx")); // 实际为 docx 模板
auto_ptr<Context> context(docTemplate->getContext());
// 1. 准备表格数据(模拟从数据库/接口获取)
vector<SalesData> salesList = {
{"产品 A", "12000 元"},
{"产品 B", "8500 元"},
{"产品 C", "15600 元"}
};
// 2. 获取模板中表格的'重复块'(需先在模板中标记表格行为重复块,名称为'salesRow')
auto_ptr<Repeat> repeat(context->getRepeat("salesRow"));
// 3. 循环填充表格行
for (const auto& data : salesList) {
repeat->next(); // 新建一行
context->replace("tableData.name", data.name); // 填充单元格 1
context->replace("tableData.sales", data.sales); // 填充单元格 2
}
// 4. 生成文档
docTemplate->generate("output_sales_report.docx");
Initialize::uninit();
cout << "表格文档生成成功!" << endl;
} catch (const Exception& e) {
cerr << "错误:" << e.what() << endl;
return 1;
}
return 0;
}
用途:生成带动态图片的文档(如证书中的 logo、报告中的图表)
前提:模板中需定义图片占位符(插入一个临时图片,命名为 ${imgLogo},后续代码会替换该位置的图片)。
#include <DocxFactory/DocxFactory.h>
#include <memory>
using namespace DocxFactory;
using namespace std;
int main() {
try {
Initialize::init();
auto_ptr<Template> docTemplate(Template::load("template_certificate.docx"));
auto_ptr<Context> context(docTemplate->getContext());
// 1. 替换文本占位符(证书基础信息)
context->replace("certUserName", "李四");
context->replace("certType", "优秀员工证书");
// 2. 插入图片(参数:占位符名、图片路径、图片宽度/高度,单位为缇 Twip,1cm≈567Twip)
// 这里将模板中 ${imgLogo} 位置替换为公司 logo,宽 3cm、高 2cm
context->insertImage(
"imgLogo", // 模板中的图片占位符名
"company_logo.png", // 本地图片路径(绝对路径或相对路径)
3 * 567, // 宽度:3cm 转换为 Twip
2 * 567 // 高度:2cm 转换为 Twip
);
// 3. 生成最终证书
docTemplate->generate("output_certificate_李四.docx");
Initialize::uninit();
cout << "带图片的证书生成成功!" << endl;
} catch (const Exception& e) {
cerr << "错误:" << e.what() << endl;
return 1;
}
return 0;
}
target。context->replaceBookmark("target", "新内容"); // 替换书签内容
DocxFactory 不直接支持条件标签,但可通过以下方式实现:
if_passed)。if (isPassed) {
context->replaceBookmark("if_passed", "通过!");
} else {
context->removeBookmark("if_passed");
}
Heading 1),代码中无需额外设置。auto_ptr<Paragraph> para = context->getParagraph("para_id");
para->setFontSize(14);
para->setBold(true);
.docx 格式,不兼容旧版 .doc。try-catch 块捕获 Exception 异常:try {
// 代码逻辑
} catch (const Exception& e) {
std::cerr << "错误:" << e.what() << std::endl;
}
python-docx:DocxFactory 基于 C++,性能更高,适合嵌入到高性能需求的 C++ 应用(如客户端软件、服务器程序);Apache POI:专注于 C++ 生态,无需 JVM 依赖,适合轻量级部署;通过以上介绍,你可高效设计出兼容、美观的 DocxFactory 模板,结合代码实现动态文档生成。从简单文本替换到复杂条件判断,模板设计的规范性是项目成功的关键。

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML 转 Markdown 互为补充。 在线工具,Markdown 转 HTML在线工具,online
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML 转 Markdown在线工具,online
通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online
将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online