windows下 Qt 操作xlsx 和 csv

news2024/11/25 14:45:34

需求:

工作中遇到一个需求,有两张表格,一个xlsx表,一个csv表格,格式如下:

以csv表格中船台标识为基础,读取xlsx中的数据,如果存在该MMSI则把船名写道csv中对应船名的后面,不存在的话,则添加进csv中,合并两个表格。由于表格数据非常多,有十几万个,所以只能通过程序判断。

提前声明:该代码仅供参考,速度很慢。建议用插件QtXlsxWriter来读写xlsx文件

代码:

pro文件

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++17

CONFIG += qaxcontainer

# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
    main.cpp \
    widget.cpp

HEADERS += \
    widget.h

FORMS += \
    widget.ui

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
namespace Ui {
class Widget;
}
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

    void readXls(const QString& file_path);
    void read_csv(const std::string& file_path);
    void write_csv(const std::string& file_path);
    void judge();

private:
    Ui::Widget *ui;

    std::vector<std::string> path_point;
    std::vector<std::string> path_xlsx;
    // QStringList str;

    std::vector<std::string> path_point_new;
    std::vector<std::string> path_xlsx_new;
    QStringList str_new;
};
#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <QFileDialog>
#include <QMessageBox>
#include <qfiledialog.h>
#include <ActiveQt/qaxobject.h>
#include <QDebug>
#include <iostream>
#include <fstream>
#include <sstream>
#include <algorithm>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    readXls("C:/Users/85720/Desktop/1.xlsx");
    read_csv("C:/Users/85720/Desktop/船名列表.CSV");
    judge();
    write_csv("C:/Users/85720/Desktop/new.CSV");
}

Widget::~Widget()
{
    delete ui;
}

// 读取csv文件
void Widget::read_csv(const std::string& file_path)
{
    std::cout<<"文件路径: "<< file_path<<"\n";
    std::ifstream csv_data(file_path, std::ios::in);
    std::string line;

    if (!csv_data.is_open()) {
        std::cout << "Error: failed to open file\n";
        std::exit(1);
    }

    std::istringstream sin;  // 将整行字符串读入到字符串流中
    std::vector<std::string> words;
    std::string word;
    // std::vector<std::vector<std::string>> path_points;
    // std::vector<std::string> path_point;
    // 读取标题行
    std::getline(csv_data, line);
    // 读取数据
    while (std::getline(csv_data, line)) {
        sin.clear();
        sin.str(line);
        words.clear();
        // std::vector<std::string> path_point;
        while (std::getline(sin, word, ',')) {  // 将字符串流sin中的字符读到word中,以字符'逗号'为分隔符
            // double value = std::atof(word.c_str());
            // qDebug() << QString::fromLocal8Bit(word.data());;
            path_point.push_back(word);
        }
        // path_points.push_back(path_point);
    }

    csv_data.close();  // 关闭文件

    // for(int i = 0; i < path_point.size(); i++)
    // {
    //     qDebug() << QString::fromLocal8Bit(path_point[i].data());
    // }
    qDebug() << "read csv over!";
    qDebug() << path_point.size();
}


void Widget::readXls(const QString& file_path)
{
    //读取excel文件
    QString readFile = file_path/*QFileDialog::getOpenFileName(this, QStringLiteral("选择Excel文件"), "", tr("Exel file(*.xls *.xlsx)"))*/;
    int row_count, col_count;
    // QStringList str;
    if (!readFile.isEmpty())
    {
        QAxObject excel("Excel.Application");
        excel.setProperty("Visible", false); //不显示Excel界面,如果为true会看到启动的Excel界面
        QAxObject* work_books = excel.querySubObject("WorkBooks");
        work_books->dynamicCall("Open (const QString&)", readFile);//打开指定文件
        QAxObject* work_book = excel.querySubObject("ActiveWorkBook");
        QAxObject* work_sheets = work_book->querySubObject("Sheets");  //获取工作表,Sheets也可换用WorkSheets
        int sheet_count = work_sheets->property("Count").toInt();  //获取工作表数目

        if (sheet_count > 0)
        {
            qDebug() << "begin read xlsx!";
            QAxObject* work_sheet = work_book->querySubObject("Sheets(int)", 1); //表格sheet,参数 "1" 代表第1个sheet
            QAxObject* used_range = work_sheet->querySubObject("UsedRange");
            QAxObject* rows = used_range->querySubObject("Rows");
            QAxObject* colums = used_range->querySubObject("Columns");
            row_count = rows->property("Count").toInt();  //获取行数
            col_count = colums->property("Count").toInt(); //获取列数
            //QString txt = work_sheet->querySubObject("Cells(int,int)", i, 1)->property("Value").toString(); //获取单元格内容
            for (int i = 2; i <= row_count; i++)
            {
                // for (int j = 1; j <= col_count; j++)
                // {
                //     QString cell = work_sheet->querySubObject("Cells(int,int)", i, j)->property("Value").toString(); //获取表格内容
                //     str.append(cell);
                //     qDebug() << cell;
                // }
                QString cell = work_sheet->querySubObject("Cells(int,int)", i, 1)->property("Value").toString(); //获取表格内容
                path_xlsx.push_back(cell.toLocal8Bit().data());
                // str.append(cell);
                // qDebug() << cell;
                cell = work_sheet->querySubObject("Cells(int,int)", i, 3)->property("Value").toString(); //获取表格内容
                path_xlsx.push_back(cell.toLocal8Bit().data());
                // str.append(cell);
                // qDebug() << cell;

            }

            work_book->dynamicCall("Close()", false);  //关闭文件
            excel.dynamicCall("Quit()");  //退出
        }
    }
    else
    {
        QMessageBox::warning(this, "提示 ", "文件路径为空!");
    }
    qDebug() << "read xlsx over!";
    qDebug() << path_xlsx.size();
}

void Widget::judge()
{
    std::vector<int> vxlsIdx;
    for(int i = 0; i < path_point.size(); i+=2)
    {
       bool flag = false;
       std::string str = path_point[i];
       std::string str2 = path_point[i+1];
       path_point_new.push_back(str);
       path_point_new.push_back(str2);
       for(int j = 0; j < path_xlsx.size(); j+=2)
       {
           if(str == path_xlsx[j])
           {
               flag = true;
               vxlsIdx.push_back(j);
               path_point_new.push_back(path_xlsx[j+1]);
               break;
           }
       }
       if(!flag)
           path_point_new.push_back("");
    }

    //---------------------------------------------
    for(int i = 0; i < path_xlsx.size(); i+=2)
    {
        auto it = std::find(vxlsIdx.begin(),vxlsIdx.end(),i);
        if(it == vxlsIdx.end()) //没找到
        {
            path_point_new.push_back(path_xlsx[i]);
            path_point_new.push_back(path_xlsx[i+1]);
            path_point_new.push_back("");
        }
    }
    qDebug() << "judge over!";
    qDebug() << path_point_new.size();
}

void Widget::write_csv(const std::string& file_path)
{
    std::cout << "写入路径为: " << file_path << "\n";
    std::ofstream out_file(file_path,std::ios::out);  // 默认通过iso::out方式进行写入,当文件不存在时会进行创建
    if (out_file.is_open()) { //判定文件是否打开
        // 写入标题行
        out_file << "船台标识" << ',' << "船名中文" << std::endl;

        // 写入数据
        for (int i = 0; i < path_point_new.size(); i+=3) {
            out_file << path_point_new[i] << ',' << path_point_new[i + 1] << ','
                     << path_point_new[i + 2] << std::endl;
        }

        out_file.close();
    }else{
        std::cout<<"文件无法打开\n";
    }
    qDebug() << "write csv over!";
}

void writeXls()
{
    // //写出excel文件
    // QAxObject writeexcel("Excel.Application");
    // writeexcel.setProperty("Visible", false);
    // writeexcel.setProperty("DisplayAlerts", false);
    // QAxObject* writework_books = writeexcel.querySubObject("WorkBooks");
    // writework_books->dynamicCall("Add");
    // QAxObject* writework_book = writeexcel.querySubObject("ActiveWorkBook");
    // QAxObject* writework_sheets = writework_book->querySubObject("Sheets");
    // QAxObject* writework_sheet = writework_sheets->querySubObject("Item(int)",1);

    // QVariantList mlist;
    // for (int i = 0; i < row_count; i++)
    // {
    //     QVariantList tempVarRow;
    //     for (int j = 0; j < col_count; j++)
    //     {
    //         tempVarRow << str[i * col_count + j]; //将表格内容写出到tempVarRow中
    //     }
    //     mlist.append(QVariant(tempVarRow));
    // }
    // QAxObject* pRange = writework_sheet->querySubObject("Range(QString)", "A1");
    // pRange = pRange->querySubObject("Resize(int,int)", row_count, col_count);
    // pRange->setProperty("Value", mlist); //写出文件

    // // 导出excel文件路径,导出文件格式最好与源文件格式相同
    // // 如读取的文件格式为.xlsx,则导出文件格式最好也为.xlsx,否则打开导出文件可能出现格式兼容问题
    // QString writefile = QFileDialog::getSaveFileName(this, QStringLiteral("选择保存路径"), "", tr("Excel file(*.xls *.xlsx)"));
    // if (writefile.isEmpty())
    // {
    //     QMessageBox::warning(this, "提示", "导出路径为空!");
    // }
    // writework_book->dynamicCall("SaveAs(const Qstring&)", QDir::toNativeSeparators(writefile)); //写出文件
    // writework_book->dynamicCall("Close()");
    // writeexcel.dynamicCall("Quit()");

    // QMessageBox::information(this, "提示", "导出完成!");


}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1803671.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

四十三、openlayers官网示例Freehand Drawing解析——在地图上自由绘制图形

想要在地图上绘制自由图形&#xff0c;只需要在new Draw的时候多加一个配置项就行。 function addInteraction() {const value typeSelect.value;if (value ! "None") {draw new Draw({source: source,type: typeSelect.value,freehand: true, //是否自由绘制});ma…

TensorRT 精度debug分析工具

tensorRT还提供了一套可用于engine生成过程中debug的工具&#xff0c;包括Polygraphy、ONNX GraphSurgeon和PyTorch-Quantization。这些小工具用处很大&#xff0c;值得花时间进一步研究。 Debug方法示例 polygraphy Polygraphy是TensorRT官方提供的一系列小工具合集&#x…

面试(02)————Java集合篇

目录 一、为什么数组索引是从0开始&#xff1f;如果从1开始不行吗&#xff1f; 二、ArrayList底层的实现原理是什么&#xff1f; ​编辑三、ArrayList list new ArrayList(10)中的list扩容几次&#xff1f; 四、如何实现数组与List之间的转换&#xff1f; 五、ArrayList…

【STM32】µC/OS-III多任务程序

【STM32】C/OS-III多任务程序 一、探究目的二、探究原理2.1 嵌入式操作系统2.1.1 RTOS2.1.2 前后台系统2.1.2 C/OS-III 三、探究过程&#xff08;实验一&#xff09;3.1 μC/OS-III环境配置3.1.1 CubeMX配置3.1.2 下载μC/OS-III源码3.1.3 KEIL环境配置3.1.4 KEIL代码更改3.1.5…

【SpringBoot】项目搭建基本步骤(整合 Mybatis)

搭建 SpringBoot 项目有两种方式&#xff1a;使用 IDEA、或者在 Spring 官网下载。 1. IDEA 创建 打开 IDEA 后&#xff0c;英文版请点击 File -> New -> Project -> Spring Initialer。 中文版请点击 文件 -> 新建 -> 项目 -> Spring Initialer。 在打开的…

编译遇到找不到pcap.so 问题

1.locate 定义pcap.so locate pcap.so 如果存在则打印所有路径 使用软连接将pcap.so 的实际位置连接到编译的lib 目录下 ln -s /usr/lib/x86_64-linux-gnu/libpcap.so /usr/lib/libpcap.so 编译 提示 说明程序中编译的目标程序需要的库与现有的不兼容&#xff0c;一般都是3…

易语言高仿植物大战僵尸

易语言高仿植物大战僵尸 效果图运行教程与部分问题解决部分源码源码领取方式下期更新预报 效果图 运行教程与部分问题解决 在第一次运行代码的时候会出现一下情况&#xff0c;让我们去下载精易模块[v10.3.5] 那怎么运行呢&#xff1f;放心我为你们准备了这个模块&#xff0c;…

2024 年最新 Python 基于百度智能云实现文字识别 OCR 详细教程

文字识别 OCR 概述 文字识别OCR&#xff08;Optical Character Recognition&#xff09;提供多场景、多语种、高精度的文字检测与识别服务&#xff0c;多项ICDAR指标居世界第一。广泛适用于金融服务、财税报销、法律政务、保险医疗、快递物流、交通出行、教育培训等场景&#…

【庞加莱几何-02】反演定理和证明

文章目录 一、说明二、 inversion和 reflection三、圆反演的定义四、广义的圆反演成圆 关键词&#xff1a;inversion、reflection 一、说明 这里是庞加莱几何的第二篇文章&#xff0c;是庞加莱基本几何属性的研究。本篇主要说清楚&#xff0c;什么是反演&#xff0c;在反演情况…

ROS基础学习-ROS通信机制进阶

ROS通信机制进阶 目录 0.简介1.常用API1.1 节点初始化函数1.1.1 C++1.1.2 Python1.2 话题与服务相关函数1.2.1 对象获取相关1.2.1.1 C++1.2.1.2 Python1.2.2 订阅对象相关1.2.2.1 C++1.2.2.2 Python1.2.3 服务对象相关函数1.2.3.1 C++1.2.3.2 Python1.2.4 客户端对象相关1.2.4.…

vue 使用 Vxe UI vxe-print 实现复杂的 Web 打印,支持页眉、页尾、分页的自定义模板

Vxe UI vue 使用 Vxe UI vxe-print 实现复杂的 Web 打印&#xff0c;支持页眉、页尾、分页的自定义模板 官方文档 https://vxeui.com 查看 github、gitee 页眉-自定义标题 说明&#xff1a;vxe-print-page-break标签用于定义分页&#xff0c;一个标签一页内容&#xff0c;超…

QT 音乐播放器【二】 歌词同步+滚动+特效

文章目录 效果图概述代码解析歌词歌词同步歌词特效 总结 效果图 概述 先整体说明一下这个效果的实现&#xff0c;你所看到的歌词都是QGraphicsObject&#xff0c;在QGraphicsView上绘制(paint)出来的。也就是说每一句歌词都是一个图元(item)。 为什么用QGraphicsView框架&…

QT中为程序加入超级管理员权限

QT中为程序加入超级管理员权限 Chapter1 QT中为程序加入超级管理员权限1. mingw编译器2. MSVC编译器3. CMAKE Chapter2 如何给QT程序添加管理员权限(UAC)的几种方法1、Qt Creator中方案一&#xff1a;&#xff08;仅适用于使用msvc编译器&#xff09;方案二&#xff1a;&#x…

【NI国产替代】产线测试:数字万用表(DMM),功率分析仪,支持定制

数字万用表&#xff08;DMM&#xff09; • 6 位数字表显示 • 24 位分辨率 • 5S/s-250KS/s 采样率 • 电源和数字 I/O 均采用隔离抗噪技术 • 电压、电流、电阻、电感、电容的高精度测量 • 二极管/三极管测试 功率分析仪 0.8V-14V 的可调输出电压&#xff0c;最大连…

【NI国产替代】高速数据采集模块,最大采样率为 125 Msps,支持 FPGA 定制化

• 双通道高精度数据采集 • 支持 FPGA 定制化 • 双通道高精度采样率 最大采样率为 125 Msps12 位 ADC 分辨率 最大输入电压为 0.9 V -3 dB 带宽为 30 MHz 支持 FPGA 定制化 根据需求编程实现特定功能和性能通过定制 FPGA 实现硬件加速&#xff0c;提高系统的运算速度FPGA…

【每日刷题】Day59

【每日刷题】Day59 &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;每日刷题&#x1f34d; &#x1f33c;文章目录&#x1f33c; 1. 1103. 分糖果 II - 力扣&#xff08;LeetCode&#xff09; 2. 1051. 高度检查器 - 力扣&#xff08…

【Vue】Vue路由-重定向

问题 网页打开时&#xff0c; url 默认是 / 路径&#xff0c;未匹配到组件时&#xff0c;会出现空白 解决方案 重定向 → 匹配 / 后, 强制跳转 /home 路径 语法 { path: 匹配路径, redirect: 重定向到的路径 }, 比如&#xff1a; { path:/ ,redirect:/home }代码示例 const…

智慧互联网医院系统的技术架构与实现

随着信息技术的迅猛发展&#xff0c;智慧互联网医院系统成为现代医疗服务的重要组成部分。该系统融合了多种先进技术&#xff0c;旨在提升医疗服务的效率和质量&#xff0c;优化患者体验。本文将深入探讨智慧互联网医院系统的技术架构及其实现方法&#xff0c;并提供相关代码示…

GPT-4o仅排第二!北大港大等6所高校联手,发布权威多模态大模型榜单!

多模态大模型视频分析能力榜单出炉&#xff1a; Gemini 1.5 Pro最强&#xff0c;GPT-4o仅排第二&#xff1f; 曾经红极一时的GPT-4V屈居第三。 3.5研究测试&#xff1a;hujiaoai.cn 4研究测试&#xff1a;askmanyai.cn Claude-3研究测试&#xff1a;hiclaude3.com 最近&#…

数据挖掘--认识数据

数据挖掘--引论 数据挖掘--认识数据 数据挖掘--数据预处理 数据挖掘--数据仓库与联机分析处理 数据挖掘--挖掘频繁模式、关联和相关性&#xff1a;基本概念和方法 数据挖掘--分类 数据挖掘--聚类分析&#xff1a;基本概念和方法 数据对象与属性类型 属性&#xff1a;是一…