天天看點

Qt資料庫應用22-檔案編碼格式識别

一、前言

在做資料導入導出的過程中,如果應用場景多了,相信各位都會遇到一個問題就是檔案編碼的問題,有些檔案是ANSI編碼,有些是utf8編碼,有些又是utf8帶bom編碼,不同的檔案編碼如果都用同一種編碼格式去解析讀取出來的資料的話,肯定會遇到亂碼的問題,這并不是Qt的問題,也不是什麼Qt亂碼的問題,而是要識别到檔案的編碼然後用對應的編碼去讀取内容,這樣就不會出現亂碼,當然亂碼的出現肯定是中文,如果檔案全部是英文數字,無論何種編碼,都不會亂碼。

二、功能特點

  1. 元件同時內建了導出資料到csv、xls、pdf和列印資料。
  2. 所有操作全部提供靜态方法無需new,資料和屬性等各種參數設定采用結構體資料,極為友善。
  3. 同時支援QTableView、QTableWidget、QStandardItemModel、QSqlTableModel等資料源。
  4. 提供靜态方法直接傳入QTableView、QTableWidget控件,自動識别列名、列寬和資料内容。
  5. 每組功能都提供單獨的完整的示例,注釋詳細,非常适合各階段Qter程式員。
  6. 原創導出資料機制,不依賴任何office元件或者作業系統等第三方庫,支援嵌入式linux。
  7. 速度超快,9個字段10萬行資料隻需要2秒鐘完成。
  8. 隻需要四個步驟即可開始急速導出海量資料比如100W條記錄到Excel。
  9. 同時提供直接寫入資料接口和多線程寫入資料接口,不卡主界面。
  10. 可設定标題、副标題、表名。
  11. 可設定導出資料的字段名、列名、列寬。
  12. 可設定末尾列自動拉伸填充,預設拉伸更美觀。
  13. 可設定是否啟用校驗過濾資料,啟用後符合規則的資料特殊顔色顯示。
  14. 可指定校驗的列、校驗規則、校驗值、校驗值資料類型。
  15. 校驗規則支援 精确等于==、大于>、大于等于>=、小于<、小于等于<=、不等于!=、包含contains。
  16. 校驗值資料類型支援 整型int、浮點型float、雙精度型double,預設文本字元串類型。
  17. 可設定随機背景顔色及需要随機背景色的列集合。
  18. 支援分組輸出資料,比如按照裝置分組輸出資料,友善檢視。
  19. 可設定csv分隔符、行内容分隔符、子内容分隔符。
  20. 可設定邊框寬度、自動填資料類型,預設自動資料類型開啟。
  21. 可設定是否開啟資料單元格樣式,預設不開啟,不開啟可以節約大概30%的檔案體積。
  22. 可設定橫向排版、紙張邊距等,比如導出到pdf以及列印資料。
  23. 提供圖文混排導出資料到pdf以及列印示例,自動分頁,支援多圖。
  24. 提供一個列印樣闆中同時包括橫向縱向排版示例。
  25. 提供靜态函數将控件截圖導出到pdf檔案。
  26. 提供靜态函數将圖檔轉成pdf檔案。
  27. 提供靜态函數将csv檔案轉成xls檔案,支援列寬表名等參數設定。
  28. 針對每列可分别設定字段對齊樣式、内容對齊樣式,包括左對齊、居中對齊、右對齊。
  29. 靈活性超高,可自由更改源碼設定對齊方式、文字顔色、背景顔色等。
  30. 支援任意excel表格軟體,包括但不限于excel2003-2021、wps、openoffice等。
  31. 純Qt編寫,支援任意Qt版本+任意編譯器+任意系統。

三、體驗位址

  1. 體驗位址:​​https://pan.baidu.com/s/1ZxG-oyUKe286LPMPxOrO2A​​ 提取碼:o05q 檔案名:bin_dataout.zip
  2. 國内站點:​​https://gitee.com/feiyangqingyun​​
  3. 國際站點:​​https://github.com/feiyangqingyun​​

四、效果圖

五、相關代碼

//檢查檔案編碼 0=ANSI 1=UTF-16LE 2=UTF-16BE 3=UTF-8 4=UTF-8BOM
int DataCsv::findCode(const QString &fileName, QString &flag)
{
    //假定預設編碼utf8
    int code = 3;
    flag = "UTF-8";

    QFile file(fileName);
    if (file.open(QIODevice::ReadOnly)) {
        //讀取3位元組用于判斷
        QByteArray buffer = file.read(3);
        quint8 b1 = buffer.at(0);
        quint8 b2 = buffer.at(1);
        quint8 b3 = buffer.at(2);
        if (b1 == 0xFF && b2 == 0xFE) {
            code = 1;
            flag = "UTF-16LE";
        } else if (b1 == 0xFE && b2 == 0xFF) {
            code = 2;
            flag = "UTF-16BE";
        } else if (b1 == 0xEF && b2 == 0xBB && b3 == 0xBF) {
            code = 4;
            flag = "UTF-8BOM";
        } else {
            //嘗試用utf8轉換,如果可用字元數大于0,則表示是ansi編碼
            QTextCodec::ConverterState state;
            QTextCodec *codec = QTextCodec::codecForName("utf-8");
            codec->toUnicode(buffer.constData(), buffer.size(), &state);
            if (state.invalidChars > 0) {
                code = 0;
                flag = "ANSI";
            }
        }

        file.close();
    }

    return code;
}