关于c++:CQt-和-WordExcelPDF-交互总结

34次阅读

共计 5759 个字符,预计需要花费 15 分钟才能阅读完成。

浏览本文大略须要 6 分钟

日常开发软件可能会遇到这类小众需要,导出数据到 WordExcel 以及 PDF文件,如果你应用 C++ 编程语言,那么能够抉择的计划不是很多,恰好最近刚好有这部分需要,整顿下这段时间踩过的坑,不便前人

读写 Word

日常开发的软件应用最多的应该是导出数据到 Word 文档中,目前能够用的计划有这几种

没有美中不足的计划,任何计划都存在长处和毛病,上面来具体看下这几种计划的优缺点以及实用场景

XML 模板替换

原理:当时编辑好一份 Word 模板,须要替换内容的
中央预留好地位,而后应用非凡字段进行标记,前面应用代码进行全量替换即可实现

长处

  • 代码量绝对较少、导出速度快
  • 跨平台,反对多个零碎,零碎不装置 office 也能导出;
  • 反对图片以及固定格局导出;

毛病

  • 导出格局固定,可扩展性不强,如果需要变动导出格局变了,那么模板也要跟着扭转;
  • 一种格局对应一份模板,如果导出格局较多,须要筹备的模板文件较多,这样比拟繁琐;
  • 须要 Word 2003 以上版本;

举个栗子

咱们先编辑一份 Word 模板文档,内容大略如下所示:

  • 将该文档另存为 Word XML 文档 XML-Template.xml
  • 读取文档内容进行变量替换
    QFile file("XML-Template.xml");
    if (!file.open(QIODevice::ReadOnly))
    {qDebug() << "open xxml file fail." << file.errorString();
        return 0;
    }
    QByteArray baContent = file.readAll();
    file.close();
    QString strAllContent = QString::fromLocal8Bit(baContent);

    strAllContent.replace("$VALUE0", "1");
    strAllContent.replace("$VALUE1", QString::fromLocal8Bit("法外狂徒张三"));
    strAllContent.replace("$VALUE2", QString::fromLocal8Bit("考试不合格"));
    strAllContent.replace("$VALUE3", "2");
    strAllContent.replace("$VALUE4", QString::fromLocal8Bit("李四"));
    strAllContent.replace("$VALUE5", QString::fromLocal8Bit("合格"));

    QFile newFile("export.doc");
    if (!newFile.open(QIODevice::WriteOnly))
    {qDebug() << "file open fail." << newFile.errorString();;
        return 0;
    }

    newFile.write(strAllContent.toLocal8Bit());
    newFile.close();
  • 保留替换后的内容, 写入文件

能够看进去这种形式比拟繁琐,重点是编辑固定的模板格局,而且编辑好后保留成 XML 格局后还须要持续调整,这种 XML 格局标签很多,不小心就批改错了,导致导出的文档打不开

这种形式适宜模板内容不太简单,内容较少的状况下应用

COM 组件形式

原理:采纳 Micro Soft公开的接口进行通信,进行读写时会关上一个 `Word 过程来交互

COM 技术概述

Qt 为咱们提供了专门进行交互的类和接口,应用 Qt ActiveX框架就能够很好的实现交互工作

长处

  • 实现简略,疾速上手;

毛病

  • 导出写入速度慢,因为相当于关上 word 文档操作;
  • Windows平台可用,其它平台生效;
  • 须要程序运行的电脑装置 office word,否则调用失败

举个栗子

应用时须要引入对应的模块,在 pro 文件引入模块

QT  *= axcontainer

打开文档写入内容

QAxObject *pWordWidget = new(std::nothrow) QAxObject;

bool bResult = pWordWidget->setControl("word.Application");

if (!bResult)
{return false;}

// 设置是否显示
pWordWidget->setProperty("Visible", false);

QAxObject *pAllDocuments = pWordWidget->querySubObject("Documents");

if(nullptr == pAllDocuments)
{return false;}

// 新建一个空白文档
pAllDocuments->dynamicCall("Add (void)");

// 获取激活的文档并应用
QAxObject *pActiveDocument = pAllDocuments->querySubObject("ActiveDocument");
if(nullptr == pActiveDocument)
{return false;}

// 插入字符串
QAxObject *pSelectObj = pWordWidget->querySubObject("Selection");
if (nullptr != pSelectObj)
{pSelectObj->dynamicCall("TypeText(const QString&)", "公众号:devstone");
}

……

能够看进去应用起来不难,对于老手敌对一点,很多写入操作方法比拟繁琐,须要本人从新封装一套接口

  • 这种计划比拟适宜那些排版比较复杂,图片、文字、表格混排的场景下,而且内容都是动态变化的,能够很好的实现定制化
  • 当然了它的毛病也不少,也有一些坑,有时候莫名其妙会失败,还有就是比方你电脑装置的 Word 没有激活,那么每次启动会弹激活窗口
  • 还有就是这种形式要求所有的门路必须是本地化的,比方 D:\\Soft\test.png
  • 应用前最好读取注册表判断以后电脑是否装置了 Office Word,如果没有装置,间接读取操作必定会解体

这种形式同样实用于写入 Excel 文件,前面再说

HTML 形式

原理:这种形式得益于 Word反对 HTML 格局导出渲染显示,那么反向也能够反对,须要咱们拼接 HTML格局内容,而后写入文件保留成 .doc格局

长处

  • 跨平台,不仅限于 Windows平台,代码可扩展性比拟好
  • 导出速度快、代码可扩大;

毛病

  • 字符串拼接 HTML 容易出错,缺失标签导出后无奈显示;
  • 插入的图片是本地图片文件的链接,导出的 word 文档拷贝到其它电脑图片无奈显示

举个栗子

QString HTML2Word::getHtmlContent()
{
    QString strHtml = "";
    strHtml += "<html>";
    strHtml += "<head>";
    strHtml += "<title> 测试生成 word 文档 </title>";
    strHtml += "<head>";
    strHtml += "<body style=\"bgcolor:yellow\">";
    strHtml += "<h1 style=\"background-color:red\"> 测试 qt 实现生成 word 文档 </h1>";
    strHtml += "<hr>";
    strHtml += "<p> 这里是插入图片 <img src=\"D:\\title.jpg"alt=\"picture\"width=\"100\"height=\"100\"></p>";
    strHtml += "</hr>";
    strHtml += "</body>";
    strHtml += "</html>";

    return strHtml;
}

// 保留写入文件
QFile file("D:/htmp2Word.doc");
if (!file.open(QIODevice::WriteOnly))
{return false;}

QTextStream out(&file);
out << getHtmlContent();
file.close();

这种形式难点在于 HTML格局拼接,任何缺失字段都会导致导出失败,适宜小众需要下导出

图片问题其实能够手动进行转化,文档导出胜利后手动拷贝内容到新的文档,这样图片就真正插入到文档中,文档发送给他人也不会失落图片了

还有一个坑就是:如果你应用 WPS 关上导出的文档,默认显示的是 web视图,须要手动进行调整

某些电脑分辨率变动也会导致生成的文档中字体等产生变动

第三方开源库

能够应用的第三方库简直没有,网络上找到的有这么几个

  • OpenOffice: 兼容性差,集成调用难度大
  • LibOffice: 太宏大,不容易集成
  • DuckX:太小众,只能简略的应用
  • docx:小众库

DuckX 库
docx 库

在读写 Word这部分,C++ 根本没有能够应用的第三方库,不像其余语言 JavaC#Python 有很多能够抉择,这个苦楚也只有 C++ 程序员可能了解了吧

所以怎么抉择还是看本人我的项目需要吧,没有美中不足的计划


下面说了这么多,都是导出生成 Wrod,那么上面来看看有那些形式能够读取显示 Word内容

这种需要应该不会很多,而且显示难度更大一些

应用 COM组件形式,即采纳 QAxWidget框架显示 `
office 文档内容,实质上就是在咱们编写的 Qt 界面上嵌入 office 的软件,这种形式其实和间接关上 Word` 查看没有啥区别,成果、性能上不如间接关上更好一些

目前个别都会采纳折中计划,把 Word 转为 PDF 进行预览加载显示,咱们晓得 PDF 渲染库比拟多,生态相对来说要好一些,在抉择上就更宽泛些,如何应用前面局部有专门介绍 PDF章节

读写 Excel

目前有一个反对比拟好的第三方库能够应用,整体应用根本能够满足日常应用

QXlsx

这款开源库反对跨平台,Linux、Windows、Mac、IOS、Android,应用形式反对动静库调用和源码间接集成,十分不便

编译反对 qmakecmake,能够依据你本人的我的项目间接集成编译,读写速度十分快

QXlsx::Document xlsx;

// 设置一些款式
QXlsx::Format titleFormat;
titleFormat.setBorderStyle(QXlsx::Format::BorderThin);  // 边框款式
titleFormat.setRowHeight(1,1,30);   // 设置行高
titleFormat.setHorizontalAlignment(QXlsx::Format::AlignHCenter);   // 设置对齐形式

// 插入文本
xlsx.write(1,1, "微信公众号:devstone", titleFormat);

// 合并单元格
xlsx.mergeCells(QXlsx::CellRange(2,1,4,4), titleFormat);

// 导出保留
xlsx.saveAs("D:/xlsx_export.xlsx");

// 增加工作表
xlsx.addSheet("devstone");

能够看到上手非常容易、各个函数命名也贴近 Qt Api,是一款十分良心的开源软件

PS: 留神该软件应用 MIT 许可协定,这样对于很多集体或者公司来说十分良心,意味着你能够无偿应用、批改该我的项目,然而必须在你我的项目中也增加同样的 MIP许可

下面也提到了,还能够应用 COM 组件的形式读写 Excel,不过有了这款开源库根本就能够辞别 COM组件形式了

读写 PDF

PDF相干开源库挺多的,给了 C++ 程序员莫大的帮忙,目前可用的次要有这些

其中 mupdfpoppler 属于功能强大然而很难编译的那种,须要有扎实的三方库编译能力,否则面对 n 个依赖库会无从下手

不过可喜的是 Github 上有两个开源库能够供选择

qpdf 库

这个库其实封装了 pdf.js库,应用 WebEngine来执行 JavaScript进而加载文件

我的项目地址

  • 间接从本地文件加载;
  • 反对从内存数据间接加载渲染 PDF 内容;

这种形式对环境有特殊要求了,如果你的我的项目应用的 Qt 版本不反对 WebEngine,那么就无奈应用

qtpdf 库

这个库是 Qt 官网亲自操刀对第三方库进行了封装,裸露的 APIQt 相似,应用起来十分难受

Qt 官网

代码构造以及应用 Demo

小试牛刀

对于如何应用,官网曾经给了咱们十分具体的步骤了,间接跟着上面几步就 OK 了

官网教程

git clone git://code.qt.io/qt-labs/qtpdf
cd qtpdf
git submodule update --init --recursive
qmake
make
cd examples/pdf/pdfviewer
qmake
make

./pdfviewer /path/to/my/file.pdf

能够看到应用了谷歌开源的 pdfium 三方库,编译时须要独自更新下载这个库,因为某些起因可能你无奈下载,不过好在有人在 GitHub上同步了这个仓库的镜像,有条件还是倡议间接下载最新稳定版的

可失常拜访的仓库地址:https://github.com/PDFium/PDFium

相干类能够看这个文档:https://developers.foxit.com/…

最初还要留神我的项目开源协定:pdfium 引擎开始来自于福昕,一个中国外乡的软件公司,Google 与其单干最终进行了开源,目前采纳的是 BSD 3-Clause 协定, 这种协定容许开发者自在应用、批改源代码,也能够批改后从新公布,容许闭源进行商业行为,不过须要你在公布的产品中蕴含原作者代码中的 BSD 协定

总结

以上就是我的项目中罕用的文档解决办法总结,当然了必定也还有其它计划能够实现,毕竟条条大路通罗马,如果你还要不错的计划和倡议欢送留言

PS: 以上计划和对应的源码编译、应用例子会对立上传到 GitHub对应的仓库,不便前人应用

取之互联网、回报互联网

原创不易,如果感觉对你有帮忙,欢送点赞、在看、转发

举荐浏览

  • Qt Creator 源码学习笔记 01,初识 QTC
  • Qt Creator 源码学习笔记 02,意识框架结构构造
  • Qt Creator 源码学习笔记 03,大型项目如何治理工程
  • Qt Creator 源码学习笔记 04,多插件实现原理剖析
  • Qt Creator 源码学习笔记 05,菜单栏是怎么实现插件化的?

正文完
 0