首页 > 编程语言 >C++读写word文档(.docx)-DuckX库的使用

C++读写word文档(.docx)-DuckX库的使用

时间:2024-11-29 12:28:47浏览次数:7  
标签:std docx duckx text C++ next 文档 doc DuckX

DuckX是一个用于创建和编辑 Microsoft Word (.docx) 文件的 C++ 库。
本文将简单介绍其用法,库的编译可见 https://blog.csdn.net/hfy1237/article/details/144129745

一、基本用法

1. 读取文档

#include <iostream>
#include "duckx.hpp"

int main() {
	duckx::Document doc("foo.docx");
	doc.open();

	for (auto p = doc.paragraphs(); p.has_next(); p.next()) {
		for (auto r = p.runs(); r.has_next(); r.next()) {
			std::cout << r.get_text() << std::endl;
		}
	}

	return 0;
}

运行结果如下:
在这里插入图片描述
中文乱码的原因时由于将UTF-8字符串使用GBK编码显示了,更改编码方案即可。

3. 添加段落

#include "duckx.hpp"
#include <iostream>

int main() {
    // 加载文档
    duckx::Document doc("foo.docx");
    doc.open();

    // 遍历段落
    duckx::Paragraph& paragraph = doc.paragraphs();
    while (paragraph.has_next()) {
        // 如果需要在某段之后插入段落
        if (paragraph.runs().get_text() == "AAA") {
            paragraph.insert_paragraph_after("This is a new paragraph.");
        }

        // 移动到下一个段落
        paragraph.next();
    }

    // 保存修改后的文档
    doc.save();

    return 0;
}

原始文件如下:
在这里插入图片描述
修改文件如下:
在这里插入图片描述

4. 添加片段

#include "duckx.hpp"
#include <iostream>

int main() {
    // 加载文档
    duckx::Document doc("foo.docx");
    doc.open();

    // 遍历段落
    duckx::Paragraph& paragraph = doc.paragraphs();
    while (paragraph.has_next()) {
        // 在某段中追加运行文本
        if (paragraph.runs().get_text() == "AAA") {
            paragraph.add_run(" Added new text here.");
        }

        // 移动到下一个段落
        paragraph.next();
    }

    // 保存修改后的文档
    doc.save();

    return 0;
}

在这里插入图片描述

3. 编辑表格

#include "duckx.hpp"
#include <iostream>

int main() {
    // 加载文档
    duckx::Document doc("table.docx");
    doc.open();

    // 遍历表格
    duckx::Table& table = doc.tables();
    while (table.has_next()) {
        duckx::TableRow& row = table.rows();
        while (row.has_next()) {
            duckx::TableCell& cell = row.cells();
            while (cell.has_next()) {
                // 在单元格内新增段落
                duckx::Paragraph& paragraph = cell.paragraphs();
                if (paragraph.runs().get_text() == "") {
                    paragraph.add_run("2024");
                }
                cell.next();
            }
            row.next();
        }
        table.next();
    }

    // 保存修改后的文档
    doc.save();

    return 0;
}

原始文档如下:
在这里插入图片描述
修改文档如下:
在这里插入图片描述

二、进阶用法

1. 文本替换

#include "duckx.hpp"
#include <iostream>
#include <unordered_map>
#include <string>

void Replace(const std::string & path, const std::unordered_map<std::string, std::string>& replacements) {
    // 打开文档
    duckx::Document doc(path);
    doc.open();

    // 遍历段落
    for (auto p = doc.paragraphs(); p.has_next(); p.next()) {
        // 遍历运行文本
        for (auto r = p.runs(); r.has_next(); r.next()) {
            // 获取当前运行文本内容
            std::string text = r.get_text();

            // 检查键值对中的键是否存在于当前文本中
            for (const auto& [key, value] : replacements) {
                // 如果找到匹配键,进行替换
                size_t pos = text.find(key);
                if (pos != std::string::npos) {
                    text.replace(pos, key.length(), value);
                    r.set_text(text);
                }
            }
        }
    }

    // 保存修改后的文档
    doc.save();
}

int main() {
    std::unordered_map<std::string, std::string> replacements = {
        {"{name}", "John Doe"},
        {"{date}", "2024-11-29"},
        {"{city}", "New York"}
    };
    Replace("foo.docx", replacements);
    std::cout << "Replacements complete. Saved to foo.docx." << std::endl;
    return 0;
}

在这里插入图片描述
在这里插入图片描述

进阶版:可同时替换普通文本和表格中的文本

#include "duckx.hpp"
#include <iostream>
#include <unordered_map>
#include <string>

void Replace(const std::string& path, const std::unordered_map<std::string, std::string>& replacements) {
    // 打开文档
    duckx::Document doc(path);
    doc.open();

    // 遍历段落
    for (auto p = doc.paragraphs(); p.has_next(); p.next()) {
        // 遍历运行文本
        for (auto r = p.runs(); r.has_next(); r.next()) {
            // 获取当前运行文本内容
            std::string text = r.get_text();

            // 检查键值对中的键是否存在于当前文本中
            for (const auto& [key, value] : replacements) {
                // 如果找到匹配键,进行替换
                size_t pos = text.find(key);
                if (pos != std::string::npos) {
                    text.replace(pos, key.length(), value);
                    r.set_text(text);
                }
            }
        }
    }

    // 遍历表格
    for (auto t = doc.tables(); t.has_next(); t.next()) {
        // 遍历表格行
        for (auto r = t.rows(); r.has_next(); r.next()) {
            // 遍历表格单元格
            for (auto c = r.cells(); c.has_next(); c.next()) {
                // 遍历单元格中的段落
                for (auto p = c.paragraphs(); p.has_next(); p.next()) {
                    // 遍历单元格段落中的运行文本
                    for (auto r = p.runs(); r.has_next(); r.next()) {
                        // 获取当前运行文本内容
                        std::string text = r.get_text();

                        // 检查键值对中的键是否存在于当前文本中
                        for (const auto& [key, value] : replacements) {
                            // 如果找到匹配键,进行替换
                            size_t pos = text.find(key);
                            if (pos != std::string::npos) {
                                text.replace(pos, key.length(), value);
                                r.set_text(text);
                            }
                        }
                    }
                }
            }
        }
    }

    // 保存修改后的文档
    doc.save();
}

int main() {
    std::unordered_map<std::string, std::string> replacements = {
        {"{name}", "John Doe"},
        {"{date}", "2024-11-29"},
        {"{city}", "New York"}
    };
    Replace("foo.docx", replacements);
    std::cout << "Replacements complete. Saved to foo.docx." << std::endl;
    return 0;
}

2. 合并文档

只能合并文本

#include "duckx.hpp"
#include <iostream>

int main() {
    // 加载第一个文档
    duckx::Document doc1("document1.docx");
    doc1.open();

    // 加载第二个文档
    duckx::Document doc2("document2.docx");
    doc2.open();

    // 将第二个文档的段落添加到第一个文档
    duckx::Paragraph &paragraph2 = doc2.paragraphs();
    while (paragraph2.has_next()) {
        // 获取第二个文档中的段落
        std::string text = paragraph2.runs().get_text();

        // 在第一个文档中插入段落
        doc1.paragraphs().insert_paragraph_after(text);

        paragraph2.next();
    }

    // 将第二个文档的表格添加到第一个文档
    duckx::Table &table2 = doc2.tables();
    while (table2.has_next()) {
        duckx::TableRow &row2 = table2.rows();
        while (row2.has_next()) {
            duckx::TableCell &cell2 = row2.cells();
            while (cell2.has_next()) {
                // 获取第二个文档中的单元格
                std::string cellText = cell2.paragraphs().runs().get_text();

                // 在第一个文档中插入单元格
                doc1.tables().rows().cells().add_run(cellText);

                cell2.next();
            }
            row2.next();
        }
        table2.next();
    }

    // 保存合并后的文档
    doc1.save();

    std::cout << "Documents merged and saved to document1.docx." << std::endl;
    return 0;
}

标签:std,docx,duckx,text,C++,next,文档,doc,DuckX
From: https://blog.csdn.net/hfy1237/article/details/144131611

相关文章

  • 精准高效-C++语言集成翔云VIN码识别接口、vin码识别sdk
    在当今快节奏的商业环境中,汽车行业面临着前所未有的挑战与机遇。无论是二手车交易、保险评估还是供应链管理,准确快速地获取车辆信息已成为提高效率、增强竞争力的关键。针对市场需求,翔云提供了VIN码识别接口,能够精确捕捉VIN码并输出,用科技的力量助力企业优化业务流程。......
  • 人脸识别API解锁智能生活、C++人脸识别接口软文
    在这个数字化转型的时代,科技正以前所未有的速度改变着我们的生活方式。其中,人脸识别技术作为人工智能领域的一项重要突破,已经逐渐渗透到我们生活的方方面面。翔云为广大有需求的用户提供了人脸识别接口解决方案,助力各行各业快速实现人脸比对功能。人脸识别接口基于深......
  • 09C++选择结构(3)
    一、求3个整数中最小值题目:输入三个整数,表示梨的重量,输出最小的数。方法1:经过三次两两比较,得出最小值。a<=b&&a<=cmin=ab<=c&&b<=amin=bc<=b&&c<=amin=c流程图:#include<typeinfo>//变量类型头文件,还是有问题;无法判断int#include<iostream>//包含输......
  • 【C++】C++11引入的新特性(2)
    当你无法从一楼蹦到三楼时,不要忘记走楼梯。要记住伟大的成功往往不是一蹴而就的,必须学会分解你的目标,逐步实施。......
  • c++的static的作用
    在C++中,static关键字有多种用途,主要可以分为以下几种:静态存储期:当static用于变量时,它表示该变量具有静态存储期,这意味着变量在程序开始时被分配内存,并在程序结束时释放内存。静态存储期的变量在函数调用之间保持其值。静态成员变量:在类中,static用于成员变量时,表示该变量是类......
  • CSP/信奥赛C++语法基础刷题训练(33):洛谷P1055:[NOIP2008 普及组] ISBN 号码
    CSP/信奥赛C++语法基础刷题训练(33):洛谷P1055:[NOIP2008普及组]ISBN号码题目描述每一本正式出版的图书都有一个ISBN号码与之对应,ISBN码包括999位数字、......
  • CSP/信奥赛C++语法基础刷题训练(34):洛谷P2241:统计方形
    CSP/信奥赛C++语法基础刷题训练(34):洛谷P2241:统计方形题目背景1997年普及组第一题题目描述有一个n×mn\timesm......
  • C++包管理器vcpkg简介
    目录安装使用安装程序包和cmake集成使用vcpkg三元组这篇文章是一个vcpkg的入门使用介绍,主要讲一些基础的内容,为了让一些不懂vcpkg的人有一个直观的认识。在开发C++程序时,你是不是也会因为复杂的程序库依赖关系而头疼,你是不是也会因为依赖的某个程序包获取复杂而抓狂......
  • 代码背后的哲思:C++特殊类实现的艺术与科学
    文章目录前言......
  • c++ 拓扑排序
    概念拓扑排序是一种线性排序算法,主要用于有向无环图(DAG,DirectedAcyclicGraph)中,对顶点进行排序,使得对于每一条边u→v,顶点u都排在顶点v之前。特点适用于有向无环图。拓扑排序的结果不唯一(如果有多种线性排序方式满足条件)。常用于任务调度、依赖关系解析、......