承接上篇,本文將介紹兩種常見的資料來源匯出方式:直接將 DataSet 的資料表輸出為 Excel,以及利用 DataView 彈性產生格式化的報表。
核心概念是將 DataSet 中第一張表的欄位標題與資料列,以 Tab (\t) 分隔欄位、換行 (\n) 分隔列的方式寫入 HttpResponse 輸出流,並設定 Content-Type 為 application/ms-Excel 觸發瀏覽器下載。
public void CreateExcel(DataSet ds, string FileName)
{
HttpResponse resp = Page.Response;
resp.ContentEncoding = System.Text.Encoding.GetEncoding("GB2312");
resp.AppendHeader("Content-Disposition", "attachment;filename=" + FileName);
string colHeaders = "", ls_item = "";
DataTable dt = ds.Tables[0];
DataRow[] myRow = dt.Select(); // 可加入篩選條件,如 dt.Select("id>10")
int cl = dt.Columns.Count;
// 寫入欄位標題
for (int i = 0; i < cl; i++)
{
if (i == (cl - 1))
colHeaders += dt.Columns[i].Caption.ToString() + "\n";
else
colHeaders += dt.Columns[i].Caption.ToString() + "\t";
}
resp.Write(colHeaders);
// 逐列寫入資料
foreach (DataRow row in myRow)
{
for (int i = 0; i < cl; i++)
{
if (i == (cl - 1))
ls_item += row[i].ToString() + "\n";
else
ls_item += row[i].ToString() + "\t";
}
resp.Write(ls_item);
ls_item = "";
}
resp.End();
}
當需要更豐富的排版(標題置中、日期格式、字串前綴、合計列、邊框、自動欄寬、跨列標題等)時,可使用 Excel COM 物件逐儲存格寫入並設定樣式。
public void OutputExcel(DataView dv, string str)
{
GC.Collect();
Application Excel = new ApplicationClass();
int rowIndex = 4, colIndex = 1;
_Workbook xBk = Excel.Workbooks.Add(true);
_Worksheet xSt = (_Worksheet)xBk.ActiveSheet;
// 寫入欄位標題 (第 4 列)
foreach (DataColumn col in dv.Table.Columns)
{
colIndex++;
Excel.Cells[4, colIndex] = col.ColumnName;
xSt.get_Range(Excel.Cells[4, colIndex], Excel.Cells[4, colIndex]).HorizontalAlignment = XlVAlign.xlVAlignCenter;
}
// 寫入資料列
foreach (DataRowView row in dv)
{
rowIndex++;
colIndex = 1;
foreach (DataColumn col in dv.Table.Columns)
{
colIndex++;
if (col.DataType == typeof(DateTime))
{
Excel.Cells[rowIndex, colIndex] = Convert.ToDateTime(row[col.ColumnName]).ToString("yyyy-MM-dd");
xSt.get_Range(Excel.Cells[rowIndex, colIndex], Excel.Cells[rowIndex, colIndex]).HorizontalAlignment = XlVAlign.xlVAlignCenter;
}
else if (col.DataType == typeof(string))
{
Excel.Cells[rowIndex, colIndex] = "'" + row[col.ColumnName].ToString();
xSt.get_Range(Excel.Cells[rowIndex, colIndex], Excel.Cells[rowIndex, colIndex]).HorizontalAlignment = XlVAlign.xlVAlignCenter;
}
else
{
Excel.Cells[rowIndex, colIndex] = row[col.ColumnName].ToString();
}
}
}
// 合計列
int rowSum = rowIndex + 1;
Excel.Cells[rowSum, 2] = "合計";
xSt.get_Range(Excel.Cells[rowSum, 2], Excel.Cells[rowSum, 2]).HorizontalAlignment = XlHAlign.xlHAlignCenter;
xSt.get_Range(Excel.Cells[rowSum, 2], Excel.Cells[rowSum, colIndex]).Interior.ColorIndex = 19; // 淺黃色
// 報表主標題 (第 2 列)
Excel.Cells[2, 2] = str;
xSt.get_Range(Excel.Cells[2, 2], Excel.Cells[2, 2]).Font.Bold = true;
xSt.get_Range(Excel.Cells[2, 2], Excel.Cells[2, 2]).Font.Size = 22;
// 自動調整欄寬
xSt.get_Range(Excel.Cells[4, 2], Excel.Cells[rowSum, colIndex]).Columns.AutoFit();
// 跨列置中標題
xSt.get_Range(Excel.Cells[2, 2], Excel.Cells[2, colIndex]).HorizontalAlignment = XlHAlign.xlHAlignCenterAcrossSelection;
// 繪製邊框
xSt.get_Range(Excel.Cells[4, 2], Excel.Cells[rowSum, colIndex]).Borders.LineStyle = 1;
xSt.get_Range(Excel.Cells[4, 2], Excel.Cells[rowSum, 2]).Borders[XlBordersIndex.xlEdgeLeft].Weight = XlBorderWeight.xlThick;
xSt.get_Range(Excel.Cells[4, 2], Excel.Cells[4, colIndex]).Borders[XlBordersIndex.xlEdgeTop].Weight = XlBorderWeight.xlThick;
xSt.get_Range(Excel.Cells[4, colIndex], Excel.Cells[rowSum, colIndex]).Borders[XlBordersIndex.xlEdgeRight].Weight = XlBorderWeight.xlThick;
xSt.get_Range(Excel.Cells[rowSum, 2], Excel.Cells[rowSum, colIndex]).Borders[XlBordersIndex.xlEdgeBottom].Weight = XlBorderWeight.xlThick;
// 儲存並下載
xBk.SaveCopyAs(Server.MapPath(".") + "\\" + this.xlfile.Text + ".xls");
// ... 後續釋放 COM 物件、Response 輸出檔案流程略 ...
}
DataSet 匯出適合快速、無格式需求的情境;DataView 搭配 Excel COM 則能產出專業報表。實務上可根據報表複雜度選擇。