十八、QT之导出数据到EXCEL

ExcelAPI.h

#ifndef EXCEL_H
#define EXCEL_H

#include 
#include 
#include 

class ExcelAPI : public QObject
{
     
    Q_OBJECT
private:
    explicit ExcelAPI(QObject *parent = 0);
    static ExcelAPI *_instance;
    QStringList html;

    void checkBorder(bool border);

public:
    static ExcelAPI *Instance() {
     
        static QMutex mutex;
        if (!_instance) {
     
            QMutexLocker locker(&mutex);
            if (!_instance) {
     
                _instance = new ExcelAPI;
            }
        }
        return _instance;
    }

    void ToExcel(QString fileName, QString sheetName, QString title, QString subTitle,
                 QList<QString> columnNames, QList<int> columnWidths,
                 QStringList content, bool border, bool check);

    void ToExcel(QString fileName, QString sheetName, QString title,
                 QList<QString> columnNames, QList<int> columnWidths,
                 QStringList subTitle1, QStringList subTitle2,
                 QStringList content, bool border, bool check);

};

#endif // EXCEL_H

ExcelAPI.cpp

#if _MSC_VER >= 1600
#pragma execution_character_set("utf-8")
#endif

#include "excelapi.h"
#include "myhelper.h"

ExcelAPI *ExcelAPI::_instance = 0;
ExcelAPI::ExcelAPI(QObject *parent) :
    QObject(parent)
{
     
}

void ExcelAPI::checkBorder(bool border)
{
     
    if (border) {
     
        html.append("  \n");
        html.append("   \n");
        html.append("   \n");
        html.append("   \n");
        html.append("   \n");
        html.append("  \n");
    }
}

void ExcelAPI::ToExcel(QString fileName, QString sheetName, QString title, QString subTitle,
                       QList<QString> columnNames, QList<int> columnWidths,
                       QStringList content, bool border, bool check)
{
     
    if (sheetName.length() == 0) {
     
        sheetName = "Sheet1";
    }

    //计算行数列数
    int columnCount = columnNames.count();
    int rowCount = content.count();

    //逐个拼接xml字符,再保存为xls文件
    //清空原有数据,确保每次都是新的数据
    html.clear();

    //固定头部信息
    html.append("\n");
    html.append("\n");
    html.append(");
    html.append(" xmlns:o=\"urn:schemas-microsoft-com:office:office\"\n");
    html.append(" xmlns:x=\"urn:schemas-microsoft-com:office:excel\"\n");
    html.append(" xmlns:ss=\"urn:schemas-microsoft-com:office:spreadsheet\"\n");
    html.append(" xmlns:html=\"http://www.w3.org/TR/REC-html40\">\n");

    //文档信息
    html.append(" \n");
    html.append("  \n");
    html.append(QString("  %1\n").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss")));
    html.append("  11.6360\n");
    html.append(" \n");

    html.append(" \n");
    html.append("  \n");
    html.append(" \n");

    html.append(" \n");
    html.append("  9795\n");
    html.append("  21435\n");
    html.append("  120\n");
    html.append("  75\n");
    html.append("  75\n");
    html.append("  False\n");
    html.append(" \n");

    //样式表
    html.append(" \n");
    html.append("  \n");

    //标题样式居中大号加粗字体
    html.append("  \n");

    //标题样式--左对齐普通字体
    html.append("  \n");

    //正文样式
    html.append("  \n");

    //正文样式--文字红色
    html.append("  \n");

    html.append(" \n");

    //工作表名称
    html.append(QString(" \n").arg(sheetName));

    //表格开始
    html.append(QString("  ).arg(columnCount));
    html.append("   x:FullRows=\"1\" ss:DefaultColumnWidth=\"54\" ss:DefaultRowHeight=\"18\">\n");//设置字段宽度for(int i =0; i < columnCount; i++){
     
        html.append(QString("   \n").arg(columnWidths.at(i)));}//表格标题if(title.length()>0){
     
        html.append("   \n");
        html.append(QString("    %2\n").arg(columnCount -1).arg(title));
        html.append("   ");}//表格副标题if(subTitle.length()>0){
     
        html.append("   \n");
        html.append(QString("    %2\n").arg(columnCount -1).arg(subTitle));
        html.append("   ");}//逐个添加字段名称if(columnCount >0){
     
        html.append("   \n");for(int i =0; i < columnCount; i++){
     
            html.append(QString("    %1\n").arg(columnNames.at(i)));}
        html.append("   \n");}//逐个添加数据for(int i =0; i < rowCount; i++){
     
        html.append("   \n");

        QString temp = content.at(i);
        QStringList value = temp.split(";");if(check){
     //如果是历史记录则文字红色if(value.at(value.count()-1)=="历史记录"){
     
                foreach (QString str, value){
     
                    html.append(QString("    %1\n").arg(str));}}else{
     
                foreach (QString str, value){
     
                    html.append(QString("    %1\n").arg(str));}}}else{
     
            foreach (QString str, value){
     
                html.append(QString("    %1\n").arg(str));}}

        html.append("   \n");}

    html.append("  
\n"
); //固定结尾格式 html.append(" \n"); html.append(" \n"); html.append("
\n"); html.append("
\n"); html.append(" \n"); html.append(" \n"); html.append(" \n"); html.append(" \n"); html.append(" False\n"); html.append(" False\n"); html.append(" \n"); html.append(" \n"); html.append("\n"); //写入文件 QFile file(fileName); if (file.open(QFile::WriteOnly | QIODevice::Text)) { QTextStream text(&file); text.setCodec("UTF-8"); text << html.join(""); } } void ExcelAPI::ToExcel(QString fileName, QString sheetName, QString title, QList<QString> columnNames, QList<int> columnWidths, QStringList subTitle1, QStringList subTitle2, QStringList content, bool border, bool check) { if (sheetName.length() == 0) { sheetName = "Sheet1"; } //计算列数 int columnCount = columnNames.count(); //逐个拼接xml字符,再保存为xls文件 //清空原有数据,确保每次都是新的数据 html.clear(); //固定头部信息 html.append("\n"); html.append("\n"); html.append("); html.append(" xmlns:o=\"urn:schemas-microsoft-com:office:office\"\n"); html.append(" xmlns:x=\"urn:schemas-microsoft-com:office:excel\"\n"); html.append(" xmlns:ss=\"urn:schemas-microsoft-com:office:spreadsheet\"\n"); html.append(" xmlns:html=\"http://www.w3.org/TR/REC-html40\">\n"); //文档信息 html.append(" \n"); html.append(QString(" %1\n").arg("")); html.append(QString(" %1\n").arg(QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss"))); html.append(" 11.6360\n"); html.append(" \n"); html.append(" \n"); html.append(" \n"); html.append(" \n"); html.append(" \n"); html.append(" 9795\n"); html.append(" 21435\n"); html.append(" 120\n"); html.append(" 75\n"); html.append(" 75\n"); html.append(" False\n"); html.append(" \n"); //样式表 html.append(" \n"); html.append(" \n"); //标题样式居中大号加粗字体 html.append(" \n"); //标题样式--左对齐普通字体 html.append(" \n"); //正文样式 html.append(" \n"); //正文样式--文字红色 html.append(" \n"); html.append(" \n"); //工作表名称 html.append(QString(" \n").arg(sheetName)); //表格开始 html.append(QString(" ).arg(columnCount)); html.append(" x:FullRows=\"1\" ss:DefaultColumnWidth=\"54\" ss:DefaultRowHeight=\"18\">\n");//设置字段宽度for(int i =0; i < columnCount; i++){ html.append(QString(" \n").arg(columnWidths.at(i)));}//表格标题if(title.length()>0){ html.append(" \n"); html.append(QString(" %2\n").arg(columnCount -1).arg(title)); html.append(" ");}//循环添加副标题/字段名/内容int count = content.count();for(int i =0; i < count; i++){ //加个空行隔开 html.append(" \n"); html.append(" ");//副标题1if(subTitle1.count()>0&& subTitle1.count()> i){ if(subTitle1.at(i).length()>0){ html.append(" \n"); html.append(QString(" %2\n").arg(columnCount -1).arg(subTitle1.at(i))); html.append(" ");}}//副标题2if(subTitle2.count()>0&& subTitle2.count()> i){ if(subTitle2.at(i).length()>0){ html.append(" \n"); html.append(QString(" %2\n").arg(columnCount -1).arg(subTitle2.at(i))); html.append(" ");}}//逐个添加字段名称if(columnCount >0){ html.append(" \n");for(int j =0; j < columnCount; j++){ html.append(QString(" %1\n").arg(columnNames.at(j)));} html.append(" \n");} QStringList list = content.at(i).split(";");//逐个添加数据int rowCount = list.count();for(int j =0; j < rowCount; j++){ html.append(" \n"); QString temp = list.at(j); QStringList value = temp.split("|");int valueCount = value.count();if(check){ //如果是历史记录则文字红色if(value.at(valueCount -1)=="1"){ for(int k =0; k < valueCount -1; k++){ html.append(QString(" %1\n").arg(value.at(k)));}}else{ for(int k =0; k < valueCount -1; k++){ html.append(QString(" %1\n").arg(value.at(k)));}}}else{ for(int k =0; k < valueCount; k++){ html.append(QString(" %1\n").arg(value.at(k)));}} html.append(" \n");}} html.append("
\n"
); //固定结尾格式 html.append(" \n"); html.append(" \n"); html.append("
\n"); html.append("
\n"); html.append(" \n"); html.append(" \n"); html.append(" \n"); html.append(" \n"); html.append(" False\n"); html.append(" False\n"); html.append(" \n"); html.append(" \n"); html.append("\n"); //写入文件 QFile file(fileName); if (file.open(QFile::WriteOnly | QIODevice::Text)) { QTextStream text(&file); text.setCodec("UTF-8"); text << html.join(""); } }

使用案例

void frmAlarm::on_btnExcel_clicked()
{
     
    QString type = "所有告警记录";
    QString defaultName = QString("%1/%2.xls").arg(App::AppPath).arg(STRDATETIME);
    QString file =  QFileDialog::getSaveFileName(this, "保存文件", defaultName, "Excel(*.xls)");

    if (file.length() == 0) {
     
        return;
    }

    QStringList content = GetContent();
    int rowCount = content.count();

    //判断数据量是否超过10000条,超过则弹出提示
    if (rowCount > 10000) {
     
        QString msg = QString("要导出的数据共 %1 条,请耐心等待!确定要导出数据吗?").arg(rowCount);
        if (myHelper::ShowMessageBoxQuestion(msg) != 1) {
     
            return;
        }
    }

    QList<int> columnWidths;
    columnWidths.append(150);
    columnWidths.append(120);
    columnWidths.append(180);
    columnWidths.append(100);
    columnWidths.append(150);

    ExcelAPI::Instance()->ToExcel(file, type, type, "", columnNames, columnWidths, content, true, false);

    QString msg = QString("导出%1到Excel").arg(type);
    DBHelper::AddEventInfoUser(msg);

    if (myHelper::ShowMessageBoxQuestion(msg + "成功!确定现在就打开吗?") == 1) {
     
        QString url = QString("file:///%1").arg(file);
        QDesktopServices::openUrl(QUrl(url, QUrl::TolerantMode));
    }
}

你可能感兴趣的:(十八、QT之导出数据到EXCEL)