首先是保存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。