實現過程:
要導出來的數據庫數據量很大,一次取出來壓力有點大,故分批取出來,導入到同一個Excel。
因為Excel2003版最大行數是65536行,Excel2007開始的版本最大行數是1048576行,故NPOI導出時候選擇了Excel2007。
Form1.cs
[csharp] view plaincopyprint?
/*
引用命名空間:
using System.IO;
using System.Threading.Tasks;
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
*/
public Form1()
{
InitializeComponent();
List<DictionaryEntry> list = new List<DictionaryEntry>(){
new DictionaryEntry(1, "XA"),
new DictionaryEntry(2, "XB")
};
cbType.BindComboBox(list);
}
private void CreateExcel(string fileName)
{
if (File.Exists(fileName))
File.Delete(fileName);
IWorkbook workbook = new XSSFWorkbook();
ISheet sheet = workbook.CreateSheet("Sheet1");
FileStream sw = File.Create(fileName);
workbook.Write(sw);
sw.Close();
}
private void btnExport_Click(object sender, EventArgs e)
{
try
{
Task.Factory.StartNew(() =>
{
txtSql.SafeCall(() =>
{
txtSql.AppendText("開始處理...\r\n");
});
BusinessType businessType = GetBusinessType();
string[] sqlWhereArray = Sql.SqlWhereArray;
string[] DateRemarkArray = Sql.DateRemarkArray;
string fileName = string.Format("{0}.xlsx", businessType.ToString());
CreateExcel(fileName);
string sqlCount = Sql.GetRecordSql(businessType, "");
int recordCount = db.ExecuteScalar(sqlCount);
int sqlIndex = 0;
int rowIndex = 0;
foreach (string sqlWhre in sqlWhereArray)
{
sqlIndex++;
FileStream fs = File.Open(fileName, FileMode.Open);
IWorkbook workbook = new XSSFWorkbook(fs);
ISheet sheet = workbook.GetSheetAt(0);
txtSql.SafeCall(() =>
{
txtSql.AppendText("條件" + sqlIndex.ToString() + ":" + DateRemarkArray[sqlIndex - 1]);
});
string sql = Sql.GetDataSql(businessType, sqlWhre);
DataTable dt = db.GetDataSet(sql).Tables[0];
int columnsCount = dt.Columns.Count;
if (sqlIndex == 1)
{
IRow row0 = sheet.CreateRow(0);
for (int m = 0; m < columnsCount; m++)
{
DataColumn dc = dt.Columns[m];
row0.CreateCell(m).SetCellValue(dc.ColumnName);
}
}
for (int i = 0; i < dt.Rows.Count; i++)
{
rowIndex++;
DataRow dr = dt.Rows[i];
IRow row = sheet.CreateRow(rowIndex);
for (int j = 0; j < columnsCount; j++)
{
row.CreateCell(j).SetCellValue(dr[j].ToString());
}
lblMsg.SafeCall(() =>
{
if(i == (dt.Rows.Count - 1))
txtSql.AppendText(" 行數:" + (i+1).ToString() + "\r\n");
lblMsg.Text = string.Format("正在導出第{0}個條件,第{1}行", sqlIndex.ToString(), (i + 1).ToString());
double x = rowIndex * 1.0 / recordCount * 100;
lblProgress.Text = string.Format("總行數:{0}, 當前完成總{1}行,百分占比:{2} %", recordCount.ToString(), rowIndex.ToString(), x.ToString("#0.0"));
});
}
FileStream outFs = new FileStream(fileName, FileMode.Open);
workbook.Write(outFs);
outFs.Close();
}
}).ContinueWith(TaskEnded);
}
catch (Exception ex)
{
MessageBox.Show("發生異常,錯誤提示:" + ex.Message);
}
}
private void TaskEnded(Task task)
{
txtSql.SafeCall(() =>
{
lblMsg.Text = "全部導出完成!";
txtSql.AppendText("處理完成!\r\n");
});
}
/*
引用命名空間:
using System.IO;
using System.Threading.Tasks;
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
*/
public Form1()
{
InitializeComponent();
List<DictionaryEntry> list = new List<DictionaryEntry>(){
new DictionaryEntry(1, "XA"),
new DictionaryEntry(2, "XB")
};
cbType.BindComboBox(list);
}
private void CreateExcel(string fileName)
{
if (File.Exists(fileName))
File.Delete(fileName);
IWorkbook workbook = new XSSFWorkbook();
ISheet sheet = workbook.CreateSheet("Sheet1");
FileStream sw = File.Create(fileName);
workbook.Write(sw);
sw.Close();
}
private void btnExport_Click(object sender, EventArgs e)
{
try
{
Task.Factory.StartNew(() =>
{
txtSql.SafeCall(() =>
{
txtSql.AppendText("開始處理...\r\n");
});
BusinessType businessType = GetBusinessType();
string[] sqlWhereArray = Sql.SqlWhereArray;
string[] DateRemarkArray = Sql.DateRemarkArray;
string fileName = string.Format("{0}.xlsx", businessType.ToString());
CreateExcel(fileName);
string sqlCount = Sql.GetRecordSql(businessType, "");
int recordCount = db.ExecuteScalar(sqlCount);
int sqlIndex = 0;
int rowIndex = 0;
foreach (string sqlWhre in sqlWhereArray)
{
sqlIndex++;
FileStream fs = File.Open(fileName, FileMode.Open);
IWorkbook workbook = new XSSFWorkbook(fs);
ISheet sheet = workbook.GetSheetAt(0);
txtSql.SafeCall(() =>
{
txtSql.AppendText("條件" + sqlIndex.ToString() + ":" + DateRemarkArray[sqlIndex - 1]);
});
string sql = Sql.GetDataSql(businessType, sqlWhre);
DataTable dt = db.GetDataSet(sql).Tables[0];
int columnsCount = dt.Columns.Count;
if (sqlIndex == 1)
{
IRow row0 = sheet.CreateRow(0);
for (int m = 0; m < columnsCount; m++)
{
DataColumn dc = dt.Columns[m];
row0.CreateCell(m).SetCellValue(dc.ColumnName);
}
}
for (int i = 0; i < dt.Rows.Count; i++)
{
rowIndex++;
DataRow dr = dt.Rows[i];
IRow row = sheet.CreateRow(rowIndex);
for (int j = 0; j < columnsCount; j++)
{
row.CreateCell(j).SetCellValue(dr[j].ToString());
}
lblMsg.SafeCall(() =>
{
if(i == (dt.Rows.Count - 1))
txtSql.AppendText(" 行數:" + (i+1).ToString() + "\r\n");
lblMsg.Text = string.Format("正在導出第{0}個條件,第{1}行", sqlIndex.ToString(), (i + 1).ToString());
double x = rowIndex * 1.0 / recordCount * 100;
lblProgress.Text = string.Format("總行數:{0}, 當前完成總{1}行,百分占比:{2} %", recordCount.ToString(), rowIndex.ToString(), x.ToString("#0.0"));
});
}
FileStream outFs = new FileStream(fileName, FileMode.Open);
workbook.Write(outFs);
outFs.Close();
}
}).ContinueWith(TaskEnded);
}
catch (Exception ex)
{
MessageBox.Show("發生異常,錯誤提示:" + ex.Message);
}
}
private void TaskEnded(Task task)
{
txtSql.SafeCall(() =>
{
lblMsg.Text = "全部導出完成!";
txtSql.AppendText("處理完成!\r\n");
});
}
Extensions.cs
[csharp] view plaincopyprint?
public static class Extensions
{
public static void SafeCall(this Control ctrl, Action callback)
{
if (ctrl.InvokeRequired)
ctrl.Invoke(callback);
else
callback();
}
public static void BindComboBox(this ComboBox cb, List<DictionaryEntry> list)
{
cb.DisplayMember = "Value";
cb.ValueMember = "Key";
cb.DataSource = list;
}
}
public static class Extensions
{
public static void SafeCall(this Control ctrl, Action callback)
{
if (ctrl.InvokeRequired)
ctrl.Invoke(callback);
else
callback();
}
public static void BindComboBox(this ComboBox cb, List<DictionaryEntry> list)
{
cb.DisplayMember = "Value";
cb.ValueMember = "Key";
cb.DataSource = list;
}
}Sql.cs
[csharp] view plaincopyprint?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DataExport
{
public enum BusinessType
{
XA = 1,
XB = 2
}
public class Sql
{
/// <summary>
/// 分批獲取sql的where條件
/// </summary>
public static string[] SqlWhereArray = {
" 條件1 ",
" 條件2 ",
" 條件3 "
};
/// <summary>
/// sql的where條件說明
/// </summary>
public static string[] DateRemarkArray = {
"20130101至20130331",
"20130401至20130630",
"20130701後",
};
/// <summary>
/// 獲取sql語句
/// </summary>
/// <param name="type"></param>
/// <param name="columns"></param>
/// <param name="sqlWhere"></param>
/// <returns></returns>
private static string GetSql(BusinessType type, string columns, string sqlWhere)
{
string sql = "";
switch (type)
{
case BusinessType.XA:
sql = string.Format(@"SELECT {0} FROMM tb1 WHERE 1=1 {1} ", columns, sqlWhere);
break;
case BusinessType.XB:
sql = string.Format(@"SELECT {0} FROMM tb2 WHERE 1=1 {1} ", columns, sqlWhere);
break;
}
return sql;
}
/// <summary>
/// 獲取總記錄數
/// </summary>
/// <param name="type"></param>
/// <param name="sqlWhere"></param>
/// <returns></returns>
public static string GetRecordSql(BusinessType type, string sqlWhere)
{
string columns = "count(*)";
return GetSql(type, columns, sqlWhere);
}
/// <summary>
/// 獲取數據
/// </summary>
/// <param name="type"></param>
/// <param name="sqlWhere"></param>
/// <returns></returns>
public static string GetDataSql(BusinessType type, string sqlWhere)
{
string columns = "";
switch (type)
{
case BusinessType.XA:
columns = @"
col1 列1,
col2 列2,
col3 列3
";
break;
case BusinessType.XB:
columns = @"
col1 列1,
col2 列2
";
break;
}
return GetSql(type, columns, sqlWhere);
}
}
}