Qt将表格table保存为excel(odbc方式)
首先是保存excel的方法,可参照:
http://dzmlmszp.blog.163.com/blog/static/179271962014819111812531/
ok,进入正题。
现在我有一个table,如图:
图中的table可以是QTableWidget或QTableView
但是我需要隐藏最后一列,不要让用户看到,则在代码中加入:
ui->tableWidget->setColumnCount(3);
运行中效果如下:
现在问题来了,怎样才能将我的table保存为excel?
参照前面的博客,我自己重写了一个OdbcExcel类进行操作,先把代码贴上:
odbcexcel.h
1 #ifndef ODBCEXCEL_H 2 #define ODBCEXCEL_H 3 4 #include <QObject> 5 #include <QStringList> 6 #include <QSqlQuery> 7 #include <QSqlDatabase> 8 #include <QSqlError> 9 #include <QTableView> 10 11 /** 12 * @brief The OdbcExcel class 13 * @author 郑泽桐 14 */ 15 16 class OdbcExcel 17 { 18 public: 19 OdbcExcel(); 20 //将数据保存为excel 21 bool static save(QString filePath,QStringList headers,QList<QStringList> data,QString comment=""); 22 //将QTableView保存为excel 23 bool static saveFromTable(QString filePath,QTableView *tableView,QString comment=""); 24 //获取错误信息 25 QString static getError(){return error;} 26 private: 27 void static printError( QSqlError error); 28 bool static insert(QSqlQuery& query, QString sheetName, QStringList slist); 29 static QString error; 30 }; 31 32 33 #endif // ODBCEXCEL_H
odbcexcel.cpp
1 #include "odbcexcel.h" 2 #include <QDebug> 3 4 OdbcExcel::OdbcExcel() 5 { 6 } 7 QString OdbcExcel::error; 8 9 bool OdbcExcel::save(QString filePath, QStringList headers, QList<QStringList> data,QString comment) 10 { 11 QString sheetName = "Sheet1"; 12 13 QSqlDatabase db = QSqlDatabase::addDatabase("QODBC","excelexport"); 14 if( !db.isValid()) 15 { 16 error="数据库驱动异常"; 17 return false; //! type error 18 } 19 20 QString dsn = "DRIVER={Microsoft Excel Driver (*.xls)};" 21 "DSN='';FIRSTROWHASNAMES=1;READONLY=FALSE;CREATE_DB=\""+filePath+"\";DBQ="+filePath; 22 db.setDatabaseName( dsn); 23 24 // open connection 25 if( !db.open()) 26 { 27 error="无法打开数据库"; 28 return false; //! db error 29 } 30 31 QSqlQuery query(db); 32 QString sql; 33 34 // drop the table if it's already exists 35 sql = QString("DROP TABLE [%1]").arg(sheetName); 36 query.exec( sql); 37 //create the table (sheet in Excel file) 38 sql = QString("CREATE TABLE [%1] (").arg(sheetName); 39 foreach (QString name, headers) { 40 sql +=QString("[%1] varchar(200)").arg(name); 41 if(name!=headers.last()) 42 sql +=","; 43 } 44 sql += ")"; 45 query.prepare( sql); 46 if( !query.exec()) { 47 OdbcExcel::printError( query.lastError()); 48 db.close(); 49 return false; 50 } 51 foreach (QStringList slist, data) { 52 insert(query,sheetName,slist); 53 } 54 55 if(!comment.isEmpty()) 56 { 57 QStringList slist; 58 slist<<comment; 59 for(int i=0,n=headers.size()-1;i<n;i++) 60 { 61 slist<<""; 62 } 63 insert(query,sheetName,slist); 64 } 65 66 db.close(); 67 return true; 68 } 69 70 bool OdbcExcel::saveFromTable(QString filePath,QTableView *tableView, QString comment) 71 { 72 QAbstractItemModel* model=tableView->model(); 73 const int column=model->columnCount(); 74 const int row=model->rowCount(); 75 76 //header 77 QStringList headers; 78 for(int i=0;i<column;i++) 79 { 80 //隐藏列 81 if(tableView->isColumnHidden(i)) 82 continue; 83 headers<<model->headerData(i,Qt::Horizontal).toString(); 84 } 85 86 //data 87 QStringList list; 88 QList<QStringList> data; 89 for(int i=0;i<row;i++) 90 { 91 if(model->index(i,0).data().isNull()) 92 continue; 93 list.clear(); 94 for(int j=0;j<column;j++){ 95 //隐藏列 96 if(tableView->isColumnHidden(j)) 97 continue; 98 list<<model->index(i,j).data().toString(); 99 } 100 data<<list; 101 } 102 return OdbcExcel::save(filePath,headers,data,comment); 103 } 104 105 void OdbcExcel::printError(QSqlError error) 106 { 107 QString sqlerr = error.text(); 108 error=sqlerr; 109 qCritical()<<sqlerr; 110 } 111 112 bool OdbcExcel::insert(QSqlQuery &query, QString sheetName, QStringList slist) 113 { 114 QString sSql = QString("INSERT INTO [%1] VALUES(").arg( sheetName); 115 for(int i=0,n=slist.size();i<n;i++) 116 { 117 sSql+=QString(":%1").arg(i); 118 if(i!=n-1) 119 sSql+=","; 120 else 121 sSql+=")"; 122 } 123 query.prepare( sSql); 124 for(int i=0,n=slist.size();i<n;i++) 125 { 126 query.bindValue(QString(":%1").arg(i),slist.at(i)); 127 } 128 if( !query.exec()) { 129 printError( query.lastError()); 130 return false; 131 } 132 return true; 133 }
接下来就是调用了,save按键的click事件:
1 QFileDialog dlg; 2 dlg.setAcceptMode(QFileDialog::AcceptSave); 3 // Qt 5 4 dlg.setDirectory(QStandardPaths::writableLocation(QStandardPaths::DesktopLocation)); 5 // Qt 4 6 // dlg.setDirectory(QDesktopServices::storageLocation(QDesktopServices::DesktopLocation)); 7 dlg.setNameFilter("*.xls"); 8 dlg.selectFile(QDate::currentDate().toString("yyyy-MM-dd.xls")); 9 if(dlg.exec()!= QDialog::Accepted) 10 return; 11 QString filePath=dlg.selectedFiles()[0]; 12 if(OdbcExcel::saveFromTable(filePath,ui->tableWidget,"注释:无")) { 13 QMessageBox::information(this,tr("提示"),tr("保存成功")); 14 } 15 else{ 16 QString msg="保存失败!\n\r"+OdbcExcel::getError(); 17 QMessageBox::critical(this,tr("错误"),tr(msg.toUtf8())); 18 }
看一下效果:
隐藏的列也不会显示出来。
调用OdbcExcel::saveFromTable函数,就可以将QTableWidget或QTableView保存为excel。
另外,我提供了save函数,可以直接将表头(QString headers)以及数据(QList<QStringList> data)保存为excel。