Linux平台C++读写Word文档(DuckX库)
1、安装cmake
如果没有cmake或者cmake版本太旧,都需要进行重新安装
此次推荐直接安装编译好的软件包
进入官网:https://cmake.org/download/
下载后直接在拷贝到系统里进行解压
添加环境变量
vim /etc/profile
添加下面这条命令,路径换成自己安装的路径
export PATH=$PATH:/root/cmake/bin
执行
source /etc/profile
2、安装DuckX库
git clone https://github.com/amiremohamadi/DuckX.git
cd DuckX
mkdir build
cd build
cmake ..
cmake --build .
make && make install
3、读取Word文档内容
文件名:test.docx
内容如下图:
#include <iostream>
#include <duckx/duckx.hpp>
int main() {
duckx::Document doc("test.docx");
doc.open();
for (auto p : doc.paragraphs())
for (auto r : p.runs())
std::cout << r.get_text() << std::endl;
}
开始编译
g++ -o word_read word_read.cpp --std=c++11 -lduckx
此时出现报错1
这是因为代码里面头文件路径不对,改一下就行了。
vim /usr/local/include/duckx/duckx.hpp
然后在编译。
此时出现报错2
报错没找到这个头文件,发现只有在代码库里存在,所以直接我直接从代码库里拷贝了一份出来
cp /root/DuckX/thirdparty/pugixml/pugixml.cpp /usr/local/include/duckx/
继续编译,成功。
执行体效果如下:
4、编辑Word文档
官方示例代码如下:
#include <iostream>
#include <duckx/duckx.hpp>
using namespace std;
int main()
{
duckx::Document doc("my_test.docx");
doc.open();
duckx::Paragraph p = doc.paragraphs().insert_paragraph_after("You can insert text in ");
p.add_run("italic, ", duckx::none); //纯文本
p.add_run("bold, ", duckx::bold); //加粗
p.add_run("underline, ", duckx::strikethrough);//删除线格式
p.add_run("superscript", duckx::superscript);//上标形式显示
p.add_run(" or ");
p.add_run("subscript, ", duckx::subscript); //下标形式显示
p.add_run("small caps, ", duckx::smallcaps); //小型大写字母形式
p.add_run("and shadows, ", duckx::shadow); //阴影效果显示
p.add_run("and of course ");
p.add_run("combine them.", duckx::bold | duckx::italic | duckx::underline | duckx::smallcaps);
doc.save();
return 0;
}
编译正常
g++ -o word_write word_write.cpp --std=c++11 -lduckx
运行后发现的确生成了my_test.docx
文档,但是我试过不管代码里面写多少东西,文件大小也不变,所以我怀疑这个文档有问题,下载到windows平台后的确发现这是个异常文件。
我去GitHub里面翻了下的确看到有人提出过类似问题,目前来看无法解决
所以只能采用另外一种思路,就是使用存在的文档进行编辑。这里我使用仓库里面的示例文档,my_test.docx
,里面只有两行内容。
然后重新执行之前编译出来的程序。此时程序执行完后文档内容如下图:
内容的的确成功的编辑上了,但是原有的内容还在,不是很符合我的需要,所以我在原有代码上进行了修改。
#include <duckx/duckx.hpp>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
int main() {
int pn = 0, rn = 0;
duckx::Document write_doc("my_test.docx");
write_doc.open();
//先判断文档本身存在多少内容,并把内容替换成我们需要的
for(auto p : write_doc.paragraphs())
{
pn++;
for (auto r : p.runs())
{
rn++;
if(r.get_text().length())
r.set_text("替换成我想要的runs");
}
}
duckx::Paragraph p2 = write_doc.paragraphs();
while(pn > 1)
{
p2 = p2.next();
pn--;
}
for (int i=0; i<10; i++)
{
char msg[128] = {0};
sprintf(msg, "这是第%d条数据!", i+1);
p2.insert_paragraph_after("");
p2.add_run(msg); //纯文本
p2 = p2.next();
}
write_doc.save();
return 0;
}
执行体后效果如下,之前的内容被正确替换了:
但是发现好像被吞了一条数据,可能还需要在慢慢调试。