zoukankan      html  css  js  c++  java
  • Qt解析CSV文件

    最近需要解析Excel文件,于是顺带写了解析CSV的代码

    定义数据类型LX::Sheet

     1 #ifndef LX_H
     2 #define LX_H
     3 
     4 #include <QString>
     5 #include <QStringList>
     6 
     7 namespace LX
     8 {
     9 class Sheet
    10 {
    11     enum FieldType{STRING, INT, DOUBLE, BOOL};
    12 public:
    13     Sheet(){}
    14     Sheet(Sheet&& rhs);
    15     Sheet &operator =(Sheet &&rhs);
    16 public:
    17     QString name;
    18     QList<QStringList> data;
    19     QList<FieldType> fieldTypes;
    20 };
    21 }
    22 
    23 #endif // LX_H
    //解析CSV文件
    1
    LX::Sheet FileParse::parseCSV(const QString &fileName) 2 { 3 LX::Sheet sheet; 4 5 int nameStartIndex = fileName.lastIndexOf('/') + 1; 6 if(nameStartIndex < 1) 7 { 8 nameStartIndex = fileName.lastIndexOf('\') + 1; 9 } 10 int nameEndIndex = fileName.lastIndexOf('.'); 11 sheet.name = fileName.mid(nameStartIndex, nameEndIndex - nameStartIndex); 12 13 QFile file(fileName); 14 if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) 15 { 16 return sheet; 17 } 18 19 QTextStream inStream(&file); 20 21 for( QString lineStr; !inStream.atEnd(); ) 22 { 23 lineStr = inStream.readLine(); 24 if(lineStr.isEmpty()) 25 { 26 continue; 27 } 28 29 sheet.data.append(splitCSVLine(lineStr)); 30 } 31 32 return qMove(sheet); 33 } 34 35 QStringList FileParse::splitCSVLine(const QString &lineStr) 36 { 37 QStringList strList; 38 QString str; 39 40 int length = lineStr.length(); 41 int quoteCount = 0; 42 int repeatQuoteCount = 0; 43 44 for(int i = 0; i < length; ++i) 45 { 46 if(lineStr[i] != '"') 47 { 48 repeatQuoteCount = 0; 49 if(lineStr[i] != ',') 50 { 51 str.append(lineStr[i]); 52 } 53 else 54 { 55 if(quoteCount % 2) 56 { 57 str.append(','); 58 } 59 else 60 { 61 strList.append(str); 62 quoteCount = 0; 63 str.clear(); 64 } 65 } 66 } 67 else 68 { 69 ++quoteCount; 70 ++repeatQuoteCount; 71 if(repeatQuoteCount == 4) 72 { 73 str.append('"'); 74 repeatQuoteCount = 0; 75 quoteCount -= 4; 76 } 77 } 78 } 79 strList.append(str); 80 81 return qMove(strList); 82 }

    生成CSV文件

     1 bool FileParse::generateCSV(const QString &fileName, const LX::Sheet &sheet)
     2 {
     3     QFile file(fileName);
     4     bool openOk = file.open(QIODevice::WriteOnly);
     5     if(!openOk)
     6     {
     7         return false;
     8     }
     9     QTextStream outStream(&file);
    10 
    11     int strCount = sheet.data.count();
    12     for(int i = 0; i < strCount; ++i)
    13     {
    14         outStream << joinCSVStrs(sheet.data.at(i));
    15         outStream << '
    ';
    16     }
    17 
    18     return true;
    19 }
     1 QString FileParse::joinCSVStrs(const QStringList &strList)
     2 {
     3     QString lineStr;
     4 
     5     int strCount = strList.count();
     6     int lastStrIndex = strCount - 1;
     7 
     8     for(int k = 0; k < strCount; ++k)
     9     {
    10         QString tarStr;
    11         bool commaFlag = false;
    12 
    13         const QString& oriStr = strList.at(k);
    14         int length = oriStr.length();
    15         for(int i = 0; i < length; ++i)
    16         {
    17             if(oriStr[i] == ',')
    18             {
    19                 tarStr.append(oriStr[i]);
    20                 commaFlag = true;
    21             }
    22             else if(oriStr[i] == '"')
    23             {
    24                 tarStr.append("""""");
    25             }
    26             else
    27             {
    28                 tarStr.append(oriStr[i]);
    29             }
    30         }
    31         if(commaFlag)
    32         {
    33             tarStr.push_front('"');
    34             tarStr.push_back('"');
    35         }
    36         if(k != lastStrIndex)
    37         {
    38             tarStr.append(',');
    39         }
    40 
    41         lineStr.append(tarStr);
    42     }
    43 
    44     return qMove(lineStr);
    45 }

    解析规则为:

    1、若逗号间无数据,仍解释为空数据

    2、若字段中含有逗号则用"将字段包含起来

    3、若数据中存在 " ,则将其替换为 """"

    转自:http://www.cnblogs.com/lixtary/p/4252586.html

  • 相关阅读:
    Python封装发送信息到钉钉群
    centos 7.6 安装php70
    小米5s plus刷机
    centos 7 安装webmin
    交易开拓者旗舰版(TB旗舰版)软件升级中如何迁移用户数据
    centos 7.6 修改vim配色方案
    centos 7.0 读写ntfs分区
    centos iptables 数据转发
    centos 7.6 配置VNC
    win下maridb 10.1.8下主从复制配置
  • 原文地址:https://www.cnblogs.com/lpxblog/p/6049074.html
Copyright © 2011-2022 走看看