导语
这篇文章主要实现了通过sql语句将表导出Excel,直接导出正常编码后的Excel,无需手动调整。最后用c++封装了一个函数,方便大家使用。
导出样例
无需做任何编码方式的手动调整
1.保证MySQL使用命令拥有导出权限
Step 1:
输入 show variables like '%secure%';
第二行的 secure_file_priv
会出现三种情况
① secure_file_prive=null ––限制mysqld 不允许导入导出
② secure_file_priv=/path/ – --限制mysqld的导入导出只能发生在默认的/path/目录下
③ secure_file_priv=’’ – --不对mysqld 的导入 导出做限制
如果这里的目录跟我一样是空,则可以忽略下一步
Step 2:
打开mysql安装目录,找到my.ini
文件
使用文档编辑工具打开(我用的是Notepad)
添加这一行secure-file-priv=""
Step 3:
这也是更改完设置之后重要的一步,在任务管理器中找到mysql.exe 并且关闭。随后重新查看show variables like '%secure%';
如果更改完成就成功,否则请重新更改。
2. 使用SQL实现表导出Excel
Sql语句,直接上例子:
SELECT* FROM
(SELECT CONVERT(('defult_id') USING gbk),
CONVERT(('student_id') USING gbk),
CONVERT(('name') USING gbk)
UNION
SELECT CONVERT((defult_id)USING gbk) as defult_id,
CONVERT((student_id)USING gbk) as student_id,
CONVERT((name)USING gbk) as name
FROM(SELECT* FROMt_student)a
) b into outfile 'L:\student.xls'
代码很简单,将我们获得的字段值直接写成一张表。然后将需要查询的值全部展示出来,这里应为要实现utf-8到gbk的转化 ,使用 as
重命名,最后联合在一起,导出表即可。
下面是用C++封装好的函数,其他的语言方式是一样的,就是查询那里不一样,sql的拼接是一样的。
//TODOd:连接数据库 ...
MYSQL mysql; //mysql连接
char query[1000]; //查询语句
MYSQL_RES* res; //这个结构代表返回行的一个查询结果集
char* str_field[100];//存字段名二维数组
//SQL语句
bool QueryMySql(string sql) {
mysql_query(&mysql, "set names gbk");
memset(query, 0, 1000);
for (int i = 0; i < sql.length(); i++) {
query[i] = sql[i];
}
if (mysql_query(&mysql, query)) //执行SQL语句
{
Utils::Log("Query failed (%s)\n");
Utils::Log(mysql_error(&mysql));
return false;
}
else {
return true;
}
}
//按照指定语句查找数据库
MYSQL_RES* GetMysqlRes(string sql) {
if (!QueryMySql(sql)) {
Utils::Log("!QueryMySql(sql)");
return NULL;
}
if (!(res = mysql_store_result(&mysql))) {
cout << "未能获得结果:" << mysql_error(&mysql) << endl;
return NULL;
}
return res;
}
//核心在这
//file_path 需要用“\” ,你的string 里的\需要这样写“\\”,以达到转义的作用。
//例如你的路径是这样的 L:\student.xls 传入的string需要是 L:\\student.xls 。
//并且需要考虑其他转义字符的影响
bool SaveTable(string sql,string file_path) {
if (!QueryMySql(sql)) {
Utils::Log("!QueryMySql(sql)");
return NULL;
}
if (!(res = mysql_store_result(&mysql))) {
cout << "未能获得结果:" << mysql_error(&mysql) << endl;
return NULL;
}
//这里可以自己考虑使用动态的方式定义str_field
memset(str_field, 0, 100);
string file_sql;
file_sql.append(" into outfile'");
file_sql.append(file_path);
file_sql.append("';");
string other_table = "select * from (SELECT ";
string converted_sql = "select ";
int num = mysql_num_fields(res);
if (num == 0) {
return false;
}
for (int i = 0; i < num; i++) {
//这里获得字段名,存于数组中,不同语言可以通过不同方式获取
str_field[i] = mysql_fetch_field(res)->name;
if (i != 0) {
other_table.append(",");
converted_sql.append(",");
}
//对字段的拼接与编码转换
other_table.append("CONVERT(('");
other_table.append(str_field[i]);
other_table.append("') USING gbk)");
//这里提前对值经行编码转换,为后面查询做准备
converted_sql.append("CONVERT((");
converted_sql.append(str_field[i]);
converted_sql.append(") USING gbk)");
converted_sql.append(" as ");
converted_sql.append(str_field[i]);
}
other_table.append(" UNION ");
other_table.append(converted_sql);
other_table.append(" from ");
other_table.append("(");
other_table.append(sql);
other_table.append(")a ");
other_table.append(") b");
//最后拼接文件名
other_table.append(file_sql);
bool isOK=QueryMySql(other_table);
if (!isOK) {
cout << "出错,出现重复命名" << endl;
return false;
}
return true;
}
-------------------------------------------------------完成-------------------------------------------------------