尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

Qt 操作 Word 文档解决方案

Qt 操作 Word 文档解决方案 目录Qt 操作 Word 文档解决方案一、方案一QAxObjectCOM 组件操作仅Windows 平台企业常用2.1 环境配置2.2 核心操作流程2.3 完整基础示例代码2.4 常用高级操作示例2.4.1 插入表格2.4.2 书签替换模板填充核心功能2.4.3 插入图片2.4.5保存为pdf文件2.5 注意事项二、跨平台第三方库方案和轻量模板替换方案银河麒麟系统上利用WPS的SDK进行WORD的二次开发仅供参考银河麒麟系统上利用WPS的SDK进行WORD的二次开发_wps sdk-CSDN博客本人觉得官方提供的个人版demo可参考性太差其中wps模块示例没图片的插入demo可参考的接口太少了个人版wps的sdk仅供了解企业的是不是要钱呢哈哈哈原来的pro适配 Qt 5.12.10 GCC 64 位 优化后的完整 .pro 工程文件适配 Qt 5.12.10 GCC 64 位 优化版完整 .pro 工程文件核心优化说明针对你原文件的问题逐一修复最终效果图如下其他的库调查说明注意1.使用其他的第三方库方案请参考我的其他文章强力推荐安装docxcpp 库银河麒麟linux环境下已验证很好使满足开发项目需求2.DocxFactory: 一个C操作word的开源库(不依赖office控件)-CSDN博客Qt 操作 Word 文档解决方案Qt 操作 Word 文档主要分为Windows 平台专用的 COM 组件方案、跨平台第三方库方案和轻量模板替换方案三大类不同方案适配不同的业务场景以下是详细的实现教程、代码示例和注意事项。一、方案一QAxObjectCOM 组件操作仅Windows 平台企业常用这是 Qt 在 Windows 下操作 Word 最成熟、功能最完整的方案基于 ActiveQt 框架调用 Word 的 COM 接口支持文档创建、读写、格式设置、表格 / 图片插入、打印、书签替换等几乎所有 Word 原生功能。2.1 环境配置前提条件Windows 系统需安装 Microsoft Office 2016 及以上版本或 WPS Office需开启 COM 组件支持项目配置.pro 文件qmake# Qt5 版本 QT core gui widgets axcontainer # Qt6 版本 QT core gui widgets axcontainer CONFIG qaxcontainer头文件引入cpp运行#include QAxObject #include QVariant #include QDebug // 如需手动初始化COM需引入Windows头文件 #include qt_windows.h2.2 核心操作流程初始化 COM 运行环境Qt GUI 线程自动初始化子线程需手动初始化创建 Word 应用程序对象设置是否显示界面获取文档集合对象新建 / 打开目标文档获取选区 / 范围对象执行文本写入、格式设置、表格 / 图片插入等操作保存文档关闭文档退出 Word 应用手动释放 COM 对象资源避免内存泄漏2.3 完整基础示例代码cpp运行#include QCoreApplication #include QAxObject #include QVariant #include QDebug int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); // 1. 创建Word应用程序对象 QAxObject *wordApp new QAxObject(Word.Application); if (wordApp-isNull()) { qDebug() Word应用启动失败请检查是否安装Office/WPS; delete wordApp; return -1; } // 2. 设置Word界面是否可见false为后台运行不弹出窗口 wordApp-setProperty(Visible, false); // 3. 获取文档集合新建空白文档 QAxObject *documents wordApp-querySubObject(Documents); QAxObject *document documents-dynamicCall(Add()).toQObject(); if (!document) { qDebug() 文档创建失败; wordApp-dynamicCall(Quit()); delete wordApp; return -1; } // 4. 获取当前选区光标位置写入文本 QAxObject *selection wordApp-querySubObject(Selection); // 写入标题文本 selection-dynamicCall(TypeText(const QString), Qt生成的Word文档标题); // 换行 selection-dynamicCall(TypeParagraph()); // 写入正文 selection-dynamicCall(TypeText(const QString), 这是通过Qt QAxObject生成的正文内容支持所有Word原生格式设置。); selection-dynamicCall(TypeParagraph()); // 5. 文本格式设置设置标题加粗、字号、居中 // 选中标题行 selection-dynamicCall(HomeKey(QVariant), 6); // wdStory6回到文档开头 selection-dynamicCall(EndKey(QVariant, QVariant), 4, 1); // wdLine4选中整行 // 设置加粗 selection-querySubObject(Font)-setProperty(Bold, true); // 设置字号 selection-querySubObject(Font)-setProperty(Size, 16); // 设置居中对齐 selection-querySubObject(ParagraphFormat)-setProperty(Alignment, 1); // 1居中对齐 #if 0 // 5. 将文档另存为 PDF (格式代码 17 代表 PDF) // 注意文件路径必须使用绝对路径且建议使用正斜杠或双反斜杠 QString savePath QDir::currentPath() /test_output.pdf; document-dynamicCall(SaveAs(const QString, int), savePath, 17); #endif // 4. 将文档保存为 Word 格式 (.docx) QString savePath QDir::currentPath() /test_output.docx; document-dynamicCall(SaveAs(const QString, int), savePath, 16); qDebug() 文档已保存至 savePath; // 7. 释放资源关闭Word document-dynamicCall(Close()); wordApp-dynamicCall(Quit()); // 手动删除COM对象避免内存泄漏 delete selection; delete document; delete documents; delete wordApp; return a.exec(); }2.4 常用高级操作示例2.4.1 插入表格cpp运行// 插入3行4列的表格 QAxObject *tables document-querySubObject(Tables); QAxObject *table tables-querySubObject(Add(QVariant, QVariant, QVariant, QVariant), selection-asVariant(), 3, 4, 1); // 给表格单元格赋值 for (int row 1; row 3; row) { for (int col 1; col 4; col) { QAxObject *cell table-querySubObject(Cell(QVariant, QVariant), row, col); cell-querySubObject(Range)-setProperty(Text, QString(第%1行第%2列).arg(row).arg(col)); delete cell; } } delete table; delete tables;2.4.2 书签替换模板填充核心功能提前在 Word 模板中设置书签通过书签名称精准替换内容是批量生成报表的常用方案cpp运行// 打开模板文档 documents-dynamicCall(Open(QString), D:/模板文档.docx); QAxObject *document wordApp-querySubObject(ActiveDocument); // 替换名称为user_name的书签内容 QAxObject *bookmark document-querySubObject(Bookmarks(QVariant), user_name); if (!bookmark-isNull()) { bookmark-dynamicCall(Select()); bookmark-querySubObject(Range)-setProperty(Text, 张三); } delete bookmark; // 替换名称为order_id的书签内容 QAxObject *bookmark2 document-querySubObject(Bookmarks(QVariant), order_id); if (!bookmark2-isNull()) { bookmark2-dynamicCall(Select()); bookmark2-querySubObject(Range)-setProperty(Text, 20251220001); } delete bookmark2;2.4.3 插入图片cpp运行QString imgPath D:/测试图片.png; QAxObject *inlineShapes document-querySubObject(InlineShapes); inlineShapes-dynamicCall(AddPicture(const QString, QVariant, QVariant, QVariant), imgPath, false, true, selection-asVariant()); delete inlineShapes;2.4.4保存为word文件// 6. 保存文档 // 4. 将文档保存为 Word 格式 (.docx) QString savePath QDir::currentPath() /test_output.docx; document-dynamicCall(SaveAs(const QString, int), savePath, 16);2.4.5保存为pdf文件// 5. 将文档另存为 PDF (格式代码 17 代表 PDF) // 注意文件路径必须使用绝对路径且建议使用正斜杠或双反斜杠 QString savePath QDir::currentPath() /test_output.pdf; document-dynamicCall(SaveAs(const QString, int), savePath, 17);2.5 注意事项COM 线程安全COM 对象只能在初始化它的线程中使用子线程操作 Word 需手动调用CoInitializeEx初始化 COM线程退出前调用CoUninitialize释放。资源释放所有通过querySubObject和dynamicCall创建的 QAxObject 对象必须手动 delete否则会造成内存泄漏Word 进程无法正常退出。版本兼容32 位 Qt 程序只能调用 32 位 Office64 位 Qt 程序只能调用 64 位 Office否则会出现组件加载失败。异常处理需判断每个 COM 对象是否为 null避免空指针崩溃可通过querySubObject(GetLastError())获取 COM 错误详情。二、跨平台第三方库方案和轻量模板替换方案银河麒麟系统上利用WPS的SDK进行WORD的二次开发仅供参考银河麒麟系统上利用WPS的SDK进行WORD的二次开发_wps sdk-CSDN博客本人觉得官方提供的个人版demo可参考性太差其中wps模块示例没图片的插入demo可参考的接口太少了个人版wps的sdk仅供了解企业的是不是要钱呢哈哈哈原来的proQT core gui network greaterThan(QT_MAJOR_VERSION, 4): QT widgets QMAKE_CXXFLAGS -stdc0x -Wno-attributes TARGET wpsDemo TEMPLATE app exists(/opt/kingsoft/wps-office/office6/libstdc.so.6){ system(ln -s /opt/kingsoft/wps-office/office6/libstdc.so.6 libstdc.so.6) LIBS libstdc.so.6 } QMAKE_LFLAGS -Wl,--rpath\\$\$ORIGIN\:$$[QT_INSTALL_LIBS]:/opt/kingsoft/wps-office/office6 QMAKE_LIBDIR ./ $$[QT_INSTALL_LIBS] /opt/kingsoft/wps-office/office6 greaterThan(QT_MAJOR_VERSION, 4){ LIBS -lrpcwpsapi_sysqt5 -lrpcetapi_sysqt5 -lrpcwppapi_sysqt5 exists(/opt/kingsoft/wps-office/office6/libcabi.so.1){ system(ln -sf /opt/kingsoft/wps-office/office6/libcabi.so.1 libcabi.so.1) LIBS libcabi.so.1 } } else{ LIBS -lrpcwpsapi -lrpcetapi -lrpcwppapi } INCLUDEPATH . \ ./et \ ./wps \ ./wpp \ ../include/common \ ../include/wps \ ../include/wpp \ ../include/et SOURCES main.cpp\ buttonlistwnd.cpp \ et/etmainwindow.cpp \ wpp/wppmainwindow.cpp \ wps/wpsmainwindow.cpp \ mainwindow.cpp HEADERS wps/wpsmainwindow.h \ et/etmainwindow.h \ wpp/wppmainwindow.h \ buttonlistwnd.h \ mainwindow.h FORMS \ mainwindow.ui DISTFILES RESOURCES \ translation.qrc适配 Qt 5.12.10 GCC 64 位 优化后的完整.pro工程文件以下是完全适配你的开发环境、彻底解决libstdc.so.6编译报错的优化版工程文件直接复制替换你原有的wpsDemo.pro即可100% 保留你原有的业务代码配置仅修复编译链接相关的核心问题。qmake# Qt 核心模块与基础配置 # 适配 Qt 5.12.10 核心模块 QT core gui network # Qt 5 及以上版本自动加载 widgets 模块 greaterThan(QT_MAJOR_VERSION, 4): QT widgets # 规范 C 标准Qt 5.12.10 完全支持 C11替代老旧的 c0x 草案标准 # 关闭无关的属性警告保留核心报错提示 QMAKE_CXXFLAGS -stdc11 -Wno-attributes # 目标可执行文件名、应用程序模板 TARGET wpsDemo TEMPLATE app # 核心修复WPS 库与 libstdc 链接配置 # 1. 定义 WPS 库根路径统一管理避免硬编码重复 WPS_OFFICE_PATH /opt/kingsoft/wps-office/office6 # 2. 优化软链接创建逻辑仅当 WPS 库存在时强制创建/更新软链接避免无效链接 exists($$WPS_OFFICE_PATH/libstdc.so.6){ # 用 ln -sf 强制覆盖避免重复创建报错确保软链接始终指向最新的库文件 system(ln -sf $$WPS_OFFICE_PATH/libstdc.so.6 $$PWD/libstdc.so.6) # 核心修复用标准 C 库链接参数替代直接写文件名彻底解决 g 找不到库的问题 # 如需强制使用 WPS 自带的 libstdc打开下面一行注释掉 -lstdc 即可 # LIBS $$PWD/libstdc.so.6 } # 标准 C 库链接推荐g 自动匹配对应架构的库无路径硬编码风险 LIBS -lstdc # 3. 规范链接搜索路径用标准 LIBS -L 替代不规范的 QMAKE_LIBDIR确保 g 能正确找到库 # 搜索优先级当前目录 Qt 系统库 WPS 库 LIBS -L$$PWD LIBS -L$$[QT_INSTALL_LIBS] LIBS -L$$WPS_OFFICE_PATH # 4. 优化运行时 rpath 配置确保程序运行时能找到所有依赖库无运行时加载失败问题 QMAKE_LFLAGS -Wl,--rpath$$ORIGIN:$$[QT_INSTALL_LIBS]:$$WPS_OFFICE_PATH # WPS SDK 库配置按需打开 # 保留你原有的 SDK 库配置按需取消注释即可已适配路径 # greaterThan(QT_MAJOR_VERSION, 4){ # LIBS -lrpcwpsapi_sysqt5 -lrpcetapi_sysqt5 -lrpcwppapi_sysqt5 # # 适配 WPS 自带的 libcabi 库 # exists($$WPS_OFFICE_PATH/libcabi.so.1){ # system(ln -sf $$WPS_OFFICE_PATH/libcabi.so.1 $$PWD/libcabi.so.1) # LIBS $$PWD/libcabi.so.1 # } # } # else{ # LIBS -lrpcwpsapi -lrpcetapi -lrpcwppapi # } # 头文件搜索路径配置 # 用 $$PWD 确保路径绝对性避免相对路径导致的头文件找不到问题 INCLUDEPATH $$PWD \ $$PWD/et \ $$PWD/wps \ $$PWD/wpp \ $$PWD/../include/common \ $$PWD/../include/wps \ $$PWD/../include/wpp \ $$PWD/../include/et # 源文件、头文件、UI、资源文件配置 # 100% 保留你原有的业务代码配置无任何改动 SOURCES main.cpp\ buttonlistwnd.cpp \ et/etmainwindow.cpp \ wpp/wppmainwindow.cpp \ wps/wpsmainwindow.cpp \ mainwindow.cpp HEADERS wps/wpsmainwindow.h \ et/etmainwindow.h \ wpp/wppmainwindow.h \ buttonlistwnd.h \ mainwindow.h FORMS \ mainwindow.ui DISTFILES RESOURCES \ translation.qrc # 编译输出提示方便排查问题 # qmake 执行时自动输出关键配置信息确认路径是否正确 message( 项目配置信息 ) message(Qt 版本$$QT_VERSION) message(Qt 库路径$$[QT_INSTALL_LIBS]) message(WPS 库路径$$WPS_OFFICE_PATH) message(项目根路径$$PWD) message()适配 Qt 5.12.10 GCC 64 位 优化版完整.pro工程文件以下优化版文件100% 完整保留你原有的业务代码、SDK 链接、资源文件等所有核心配置仅针对编译链接阶段的核心问题做修复彻底解决libstdc.so.6找不到、路径不兼容、编译警告等问题直接替换你原有的wpsDemo.pro即可正常编译。qmake# Qt 核心模块与基础配置100%保留你的原有配置 QT core gui network greaterThan(QT_MAJOR_VERSION, 4): QT widgets # 优化1更新为正式版 C11 标准适配 Qt 5.12.10 编译特性替代老旧的 c0x 草案 # 保留你原有的警告关闭配置 QMAKE_CXXFLAGS -stdc11 -Wno-attributes TARGET wpsDemo TEMPLATE app # 核心修复WPS 库与 libstdc 链接配置 # 优化2定义 WPS 库根路径统一管理硬编码避免重复书写 WPS_OFFICE_PATH /opt/kingsoft/wps-office/office6 # 优化3修复 libstdc.so.6 找不到的核心问题 # 仅当 WPS 库存在时强制创建/更新软链接避免重复创建报错 exists($$WPS_OFFICE_PATH/libstdc.so.6){ # 用 ln -sf 强制覆盖确保软链接始终指向有效库文件 system(ln -sf $$WPS_OFFICE_PATH/libstdc.so.6 $$PWD/libstdc.so.6) # 核心修复优先使用标准 C 库链接参数g 自动匹配对应架构的库 # 如需强制使用 WPS 自带的 libstdc取消下面一行的注释即可 # LIBS $$PWD/libstdc.so.6 } # 标准 C 库链接推荐彻底解决 g 找不到库的问题 LIBS -lstdc # 优化4规范链接搜索路径用标准 LIBS -L 替代不规范的 QMAKE_LIBDIR # 搜索优先级当前目录 Qt 系统库 WPS 库确保 g 能正确找到所有依赖 LIBS -L$$PWD LIBS -L$$[QT_INSTALL_LIBS] LIBS -L$$WPS_OFFICE_PATH # 优化5修复 rpath 转义问题确保运行时库搜索路径正确生效 QMAKE_LFLAGS -Wl,--rpath$$ORIGIN:$$[QT_INSTALL_LIBS]:$$WPS_OFFICE_PATH # WPS SDK 库配置100%完整保留你的原有逻辑 greaterThan(QT_MAJOR_VERSION, 4){ LIBS -lrpcwpsapi_sysqt5 -lrpcetapi_sysqt5 -lrpcwppapi_sysqt5 exists($$WPS_OFFICE_PATH/libcabi.so.1){ # 优化为强制覆盖软链接避免重复创建报错 system(ln -sf $$WPS_OFFICE_PATH/libcabi.so.1 $$PWD/libcabi.so.1) LIBS $$PWD/libcabi.so.1 } } else{ LIBS -lrpcwpsapi -lrpcetapi -lrpcwppapi } # 头文件搜索路径配置优化为绝对路径避免找不到头文件 # 优化6用 $$PWD 前缀确保路径绝对性适配不同编译工作目录彻底解决头文件找不到问题 INCLUDEPATH $$PWD \ $$PWD/et \ $$PWD/wps \ $$PWD/wpp \ $$PWD/../include/common \ $$PWD/../include/wps \ $$PWD/../include/wpp \ $$PWD/../include/et # 源文件、头文件、UI、资源文件100%完整保留你的原有配置 SOURCES main.cpp\ buttonlistwnd.cpp \ et/etmainwindow.cpp \ wpp/wppmainwindow.cpp \ wps/wpsmainwindow.cpp \ mainwindow.cpp HEADERS wps/wpsmainwindow.h \ et/etmainwindow.h \ wpp/wppmainwindow.h \ buttonlistwnd.h \ mainwindow.h FORMS \ mainwindow.ui DISTFILES RESOURCES \ translation.qrc # 编译信息输出方便你排查配置问题 # qmake 执行时自动输出关键配置确认路径、版本是否正确 message( 项目编译配置信息 ) message(Qt 版本$$QT_VERSION) message(Qt 库安装路径$$[QT_INSTALL_LIBS]) message(WPS 库根路径$$WPS_OFFICE_PATH) message(项目根目录$$PWD) message(C 编译标准$$QMAKE_CXXFLAGS) message(链接搜索路径$$LIBS) message(运行时 rpath 路径$$QMAKE_LFLAGS) message()核心优化说明针对你原文件的问题逐一修复表格原文件问题优化方案解决的核心问题直接写LIBS libstdc.so.6g 链接时找不到文件替换为标准的LIBS -lstdcg 自动匹配对应架构的 C 标准库彻底解决g: error: libstdc.so.6: No such file or directory核心编译报错用不规范的QMAKE_LIBDIR设置链接搜索路径部分 g 版本无法正确识别替换为 Qt 标准的LIBS -Lxxx写法明确告诉 g 库文件的搜索目录确保 g 能正确找到当前目录、Qt 库、WPS 库中的所有依赖文件无路径解析问题软链接创建用ln -s重复执行 qmake 会报错无法更新软链接优化为ln -sf强制覆盖仅当 WPS 库文件存在时才执行避免软链接创建报错确保软链接始终指向有效的 WPS 库文件不会出现无效链接用老旧的-stdc0x草案标准Qt 5.12.10 已完全支持正式版 C11更新为-stdc11正式标准适配 Qt 5.12.10 的编译特性避免 C 标准不兼容导致的编译警告 / 报错提升代码稳定性适配 WPS SDK 的 C 接口头文件路径用相对路径不同编译工作目录下可能找不到头文件统一用$$PWD前缀确保所有头文件路径为绝对路径彻底解决头文件找不到的编译报错适配 Qt Creator 构建目录、命令行编译等不同场景rpath 配置有多余的转义字符\\$\$ORIGIN\部分 g 版本无法正确解析优化为$$ORIGIN标准写法确保运行时库搜索路径正确生效避免运行时报error while loading shared libraries依赖库加载失败问题确保程序在任意目录都能正常运行无编译配置信息输出出现问题时难以排查路径 / 版本错误新增message配置qmake 执行时自动输出关键配置信息快速确认 Qt 版本、库路径、编译参数是否正确大幅降低问题排查成本最终效果图如下注意上面其中的一种方法本人感觉参考的demo过于简单wps模块图片插入功能没找到还有很多地方不太灵活其他的库调查说明注意1.使用其他的第三方库方案请参考我的其他文章强力推荐安装docxcpp 库银河麒麟linux环境下已验证很好使满足开发项目需求2.DocxFactory: 一个C操作word的开源库(不依赖office控件)-CSDN博客亲测DocxFactory 依赖其他的第三方库的太多安装比较麻烦其中依赖库zint库未编过调查该库是二维码相关的库通过咨询豆包如果qt实现word的基本的操作可以不用依赖zint可以在源代码里面配置屏蔽zint的使用只编译DocxFactory但源码中DocxFactory/DocxFactory.h文件没找到本人怀疑源码目前可能使用DocxFactory/os/OsFunc.h和src/os/OsFunc.cpp我只调查到这里配置地方有些多比较麻烦以后需要的话有时间再调查吧综合目前推荐docxcpp库无第三方库依赖对开发环境要求不高比较适合一般项目企业要求。zint源码下载路径GitHub - zint/zint: A barcode encoding library supporting over 50 symbologies including Code 128, Data Matrix, USPS OneCode, EAN-128, UPC/EAN, ITF, QR Code, Code 16k, PDF417, MicroPDF417, LOGMARS, Maxicode, GS1 DataBar, Aztec, Composite Symbols and more. · GitHub
返回列表