亲宝软件园·资讯

展开

Qt csv转xls

feiyangqingyun 人气:0

一、前言

最近又多了个需求就是将csv格式的文件转xls,需求一个接着一个,还好都是真实的需求,而且都是有用的需求,并不是不靠谱的需求,不靠谱的需求就比如程序自动识别手机壳颜色自动换背景颜色或者边框颜色色系。csv转xls,因为很多软件或者网页为了跨平台做了极致简单的导出数据形式,那就是csv格式的文本数据,有些用户觉得这种格式用电子表格软件打开后,格式显得很拥挤不好看,所以需要自己的程序能够提供静态函数直接进行转换,里面有多少个字段,转成xls数据后也多少个字段,有多少行内容也就多少行内容,这样打开后就是标准的xls文件,带有一定格式。

之前封装的通用导出函数就支持直接传入数据集合和字段集合导出,所以这个需求的难点及主要工作量就是读取csv文件,取出字段集合和内容集合,最后赋值给数据导出结构体即可。如果是标准的csv文件,那还是很容易读取的,搞个QFile搭配QTextStream以文本流的形式一行行readLine读取,理想很好显示很打脸,自己按照标准csv要求导出的文件可以正常转换,而用户第三方软件导出的csv格式的文件死活无法ok,用记事本打开一看,居然是bom格式,而且里面穿插了非常多的无效空格以及不可见字符\x200B,bom字节也好,不可见字符也好,用普通的QString是打印不出来的,必须转成QByteArray然后再转成16进制字符串就能看到,bom是文本最开始前面三个固定字节0xEF、0xBB、0xBF,只要读取到文件前面存在这三个字节就说明是带bom的文件。

格式搞明白了,代码自然就出来了,通过readLine拿到数据后,传入正则表达式调用remove方法移除不可见字符,这样剩下的就是可见字符,然后判断当前是否读取的是第一行,是第一行则数据分割后传入列名字段名称集合中,其余都是一行行数据,按照要求的分隔符传入队列即可,最后一次性调用静态数据导出函数打完收工,完美!总结:遇到困难要迎难而上,只要功夫深,一定能找到问题所在,尤其是代码写的多了以后,遇到问题会有多种甚至几十种解决办法。

二、功能特点

三、体验地址

体验地址:http://pan.baidu.com/s/1eeL5MTz0rifwtVLegRpkoQ  提取码:erxm 文件名:bin_dataout.zip

国内站点:https://gitee.com/feiyangqingyun

国际站点:https://github.com/feiyangqingyun

四、效果图

五、相关代码

QString DataOther::csvToXls(DataContent &dataContent, const QString &csvFile, const QString &xlsFile, bool quatation, const QString &spliter)
{
    //为空则同名文件
    QString fileName = xlsFile;
    if (fileName.isEmpty()) {
        fileName = csvFile;
        fileName.replace("." + QFileInfo(csvFile).suffix(), ".xls");
    }

    //内容集合
    QStringList content;
    //字段名称
    QList<QString> columnNames;
    //字段宽度
    QList<int> columnWidths;

    //读取csv文件的内容
    QFile file(csvFile);
    if (file.open(QIODevice::ReadOnly | QFile::Text)) {
        //采用文件流的形式读取速度最快
        QTextStream stream(&file);
        DataCsv::initTextStream(csvFile, &stream);
        stream.seek(0);

        //循环读取文件
        int row = 0;
        while (!stream.atEnd()) {
            QString line = stream.readLine();
            if (line.isEmpty()) {
                continue;
            }

            //删除特殊字符,这个字符会导致读取不到内容TNND
            QString pattern = "[\\x200B]";
#if (QT_VERSION >= QT_VERSION_CHECK(6,0,0))
            line.remove(QRegularExpression(pattern));
#else
            line.remove(QRegExp(pattern));
#endif

            row++;
            QStringList list = line.split(spliter);
            //第一行是字段
            if (row == 1) {
                int count = list.count();
                for (int i = 0; i < count; ++i) {
                    //去掉空字段名
                    QString columnName = list.at(i);
                    if (columnName.isEmpty()) {
                        continue;
                    }

                    columnNames << columnName;
                    //设置过则取设置好的
                    if (dataContent.columnWidths.count() > i) {
                        columnWidths << dataContent.columnWidths.at(i);
                    } else {
                        columnWidths << 70;
                    }
                }
                continue;
            }

            QString separator = dataContent.separator;
            //每行数据作为一个整体字符串带分割符 ; 存入
            content << list.join(separator);
        }
    }

    if (content.count() > 0) {
        //填充内容
        dataContent.content = content;
        //设置列名列宽
        dataContent.columnNames = columnNames;
        dataContent.columnWidths = columnWidths;
        //设置文件名
        dataContent.fileName = fileName;
        //调用静态函数导出
        DataXls::saveXls(dataContent);
    }

    return fileName;
}

加载全部内容

相关教程
猜你喜欢
用户评论