2020-04-17
2020-04-20更新
Default.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="GridViewtoDataTableTest.Default" %> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title></title> </head> <body> <form id="form1" runat="server"> <div> <asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:TestDBConnectionString %>" SelectCommand="SELECT * FROM [TestTable]"></asp:SqlDataSource><br /> <asp:GridView ID="GridView1" runat="server" AllowPaging="True" AllowSorting="True" AutoGenerateColumns="False" DataSourceID="SqlDataSource1">
<Columns>
<asp:BoundField DataField="no" HeaderText="no" InsertVisible="False" ReadOnly="True" SortExpression="no" />
<asp:BoundField DataField="myname" HeaderText="myname" SortExpression="myname" />
<asp:BoundField DataField="addr" HeaderText="addr" SortExpression="addr" />
<asp:BoundField DataField="myname2" HeaderText="myname2" SortExpression="myname2" Visible="false" />
<asp:TemplateField HeaderText="addr2" SortExpression="addr2">
<EditItemTemplate>
<asp:TextBox ID="TextBox1" runat="server" Text='<%# Bind("addr2") %>'></asp:TextBox>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Bind("addr2") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView><br />
<asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" /><br />
<asp:Label ID="Label_MSG1" runat="server"></asp:Label>
</div>
</form>
</body>
</html>
|
上面 myname2 欄位因為 Visible="false",GridViewtoDataTable() 產出結果會只剩下標題,沒有內容。
上面 addr2 欄位因為執行【將這個欄位轉為 TemplateField】,GridViewtoDataTable() 產出結果會只剩下標題。
GridViewtoDataTable() 可能要再研究改良。
Default.aspx.cs
using ClosedXML.Excel;
using System;
using System.Data;
using System.Text;
using System.Web;
using System.Web.UI.WebControls;
namespace GridViewtoDataTableTest
{
public partial class Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void Button1_Click(object sender, EventArgs e)
{
Label_MSG1.Text = "";
if (GridView1.Rows.Count == 0)
{
Label_MSG1.Text = "無可匯出資料。";
Label_MSG1.ForeColor = System.Drawing.Color.Red;
return;
}
var wb = new XLWorkbook();
DataTable dataTable = GridViewtoDataTable(GridView1);
//Worksheet names cannot be empty
dataTable.TableName = "工作表1";
wb.Worksheets.Add(dataTable);
string mainFileName = "匯出檔案";
//DateTime.Now.ToString("yyyyMMddHHmmssfff") + ".xlsx";
// 使用者若很多,最好連 fff 也用上
//DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss-fff") + ".xlsx";
// 若檔案名稱有中文字或特殊符號,Response.AddHeader() 輸出檔案名稱要編碼
string outFileName = HttpUtility.UrlEncode(mainFileName, System.Text.Encoding.UTF8) + "-" +
DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss-fff") + ".xlsx";
// XLWorkbook.SaveAs() 輸出檔案名稱不要用 HttpUtility.UrlEncode 編碼
// Response.TransmitFile() 輸出檔案名稱不要用 HttpUtility.UrlEncode 編碼
string dirFileName = @"D:\Production\TempImageFiles\" + mainFileName + "-" +
DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss-fff") + ".xlsx";
//wb.SaveAs("Export.xlsx");
// Visual Studio 下 Debug 會存到 C:\Program Files (x86)\IIS Express\
wb.SaveAs(dirFileName);
// 跳出下載視窗 Response.Clear(); Response.Buffer = true; Response.ContentEncoding = Encoding.GetEncoding(950); //950就是所謂的BIG5 //Response.AddHeader("Content-Disposition", "attachment;filename=\"" + // HttpUtility.UrlEncode(fileName, System.Text.Encoding.UTF8) + "-" + // DateTime.Now.ToString("yyyyMMddHHmmss") + ".xlsx"); Response.AddHeader("Content-Disposition", "attachment;filename=\"" + outFileName); //'Excel 2003 : "application/vnd.ms-excel" //'Excel 2007 : "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" //Extension MIME Type //.xlsx application/vnd.openxmlformats-officedocument.spreadsheetml.sheet //.xltx application/vnd.openxmlformats-officedocument.spreadsheetml.template //.potx application/vnd.openxmlformats-officedocument.presentationml.template //.ppsx application/vnd.openxmlformats-officedocument.presentationml.slideshow //.pptx application/vnd.openxmlformats-officedocument.presentationml.presentation //.sldx application/vnd.openxmlformats-officedocument.presentationml.slide //.docx application/vnd.openxmlformats-officedocument.wordprocessingml.document //.dotx application/vnd.openxmlformats-officedocument.wordprocessingml.template //.xlam application/vnd.ms-excel.addin.macroEnabled.12 //.xlsb application/vnd.ms-excel.sheet.binary.macroEnabled.12 //Response.ContentType = "application/ms-excel"; Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"; //Response.TransmitFile(@"C:\Program Files (x86)\IIS Express\Export.xlsx"); //dirFileName = dirFileName.Replace('\\', '/'); //轉換 Windows, Linux 不同路徑斜線 //dirFileName = dirFileName.Replace("/", "\\"); // 轉換斜線 / 成 \ ,因 \ 是特殊符號,要以 \\ 表示 Response.TransmitFile(dirFileName); Response.End(); } public static DataTable GridViewtoDataTable(GridView gv) { //GridView2DataTable // 只會抓 <asp:BoundField DataField="myname" HeaderText="myname" SortExpression="myname" /> 這類的值, // 執行【將這個欄位轉為 TemplateField】的欄位不會被抓到。 gv.AllowSorting = false; // 支援排序時,標題不是文字,要改抓 LinkButton 的文字,麻煩,不如暫時取消 gv.AllowPaging = false; // 分頁狀態下,只能抓到當頁的10筆,必須取消分頁 gv.DataBind(); DataTable dt = new DataTable(); DataColumn dc; DataRow dr; for (int i = 0; i < gv.Columns.Count; i++) { dc = new DataColumn(); dc.ColumnName = gv.Columns[i].HeaderText; dt.Columns.Add(dc); } for (int i = 0; i < gv.Rows.Count; i++) { dr = dt.NewRow(); for (int j = 0; j < gv.Columns.Count; j++) { dr[j] = gv.Rows[i].Cells[j].Text; } dt.Rows.Add(dr); } gv.AllowSorting = true; gv.AllowPaging = true; gv.DataBind(); return dt; } } } |
解決欄位 Visible="false" 問題,標題和資料內容都不會產出了。
public static DataTable GridViewtoDataTable(GridView gv) { //GridView2DataTable // 只會抓 <asp:BoundField DataField="myname" HeaderText="myname" SortExpression="myname" /> 這類的值, // 執行【將這個欄位轉為 TemplateField】的欄位不會被抓到。 gv.AllowSorting = false; // 支援排序時,標題不是文字,要改抓 LinkButton 的文字,麻煩,不如暫時取消 gv.AllowPaging = false; // 分頁狀態下,只能抓到當頁的10筆,必須取消分頁 gv.DataBind(); DataTable dt = new DataTable(); DataColumn dc; DataRow dr; for (int i = 0; i < gv.Columns.Count; i++) { dc = new DataColumn(); dc.ColumnName = gv.Columns[i].HeaderText; if (gv.Columns[i].Visible != false) { dt.Columns.Add(dc); } } int index = 0; for (int i = 0; i < gv.Rows.Count; i++) { dr = dt.NewRow(); index = 0;for (int j = 0; j < gv.Columns.Count; j++) { if (gv.Columns[j].Visible != false) { //dr[j] = gv.Rows[i].Cells[j].Text; dr[index] = gv.Rows[i].Cells[j].Text; index++; } } dt.Rows.Add(dr); } gv.AllowSorting = true; gv.AllowPaging = true; gv.DataBind(); return dt; } |
執行【將這個欄位轉為 TemplateField】的欄位不會被抓到或可參考下面
http://shaurong.blogspot.com/2016/03/caspnet-gridview-excel-xlsx-openxml-sdk.html
public static DataTable GridViewtoDataTable(GridView gv) { //GridView2DataTable // 只會抓 <asp:BoundField DataField="myname" HeaderText="myname" SortExpression="myname" /> 這類的值, // 執行【將這個欄位轉為 TemplateField】的欄位不會被抓到。 gv.AllowSorting = false; // 支援排序時,標題不是文字,要改抓 LinkButton 的文字,麻煩,不如暫時取消 gv.AllowPaging = false; // 分頁狀態下,只能抓到當頁的10筆,必須取消分頁 gv.DataBind(); DataTable dt = new DataTable(); DataColumn dc; DataRow dr; for (int i = 0; i < gv.Columns.Count; i++) { dc = new DataColumn(); dc.ColumnName = gv.Columns[i].HeaderText; if (gv.Columns[i].Visible != false) { dt.Columns.Add(dc); } } int index = 0; for (int i = 0; i < gv.Rows.Count; i++) { dr = dt.NewRow(); index = 0; for (int j = 0; j < gv.Columns.Count; j++) { if (gv.Columns[j].Visible != false) { //dr[j] = gv.Rows[i].Cells[j].Text; dr[index] = gv.Rows[i].Cells[j].Text; if (gv.Rows[i].Cells[j].HasControls()) { for (int k=0;k< gv.Rows[i].Cells[j].Controls.Count; k++) { if (gv.Rows[i].Cells[j].Controls[k] is Label) { Label labelControl = gv.Rows[i].Cells[j].Controls[k] as Label; //Label labelControl = (Label)gv.Rows[i].Cells[j].FindControl("Label1"); if (labelControl != null) { string labelText = labelControl.Text; dr[index] = labelText; } } } } index++; } } dt.Rows.Add(dr); } gv.AllowSorting = true; gv.AllowPaging = true; gv.DataBind(); return dt; } |
補充:如果不做下面設定
gv.AllowSorting = false; // 支援排序時,標題不是文字,要改抓 LinkButton 的文字,麻煩,不如暫時取消 |
標題純文字這樣抓
// 標題純文字這樣抓 for (int i = 0; i < girdViewtest.HeaderRow.Cells.Count; i++) { dt.Columns.Add(girdViewtest.HeaderRow.Cells[i].Text.Replace(" ", "")); } // 如果 GridView 設定為可排序,header 就要改抓 LinkButton 的文字 for (int i = 0; i < gridView.HeaderRow.Cells.Count; i++) { if (gridView.HeaderRow.Cells[i].HasControls()) { // 如果 GridView 設定為可排序,header 就要改抓 LinkButton 的文字 // Linkbutton is in index 0 of the control if (gridView.HeaderRow.Cells[i].Controls[0] is LinkButton) { LinkButton headerControl = gridView.HeaderRow.Cells[i].Controls[0] as LinkButton; string headerName = headerControl.Text; } } } |
2020-04-27 改為下面
public static DataTable GridViewtoDataTable(GridView gv) { //GridView2DataTable // 只會抓 <asp:BoundField DataField="myname" HeaderText="myname" SortExpression="myname" /> 這類的值, // 執行【將這個欄位轉為 TemplateField】的欄位不會被抓到。 gv.AllowSorting = false; // 支援排序時,標題不是文字,要改抓 LinkButton 的文字,麻煩,不如暫時取消 gv.AllowPaging = false; // 分頁狀態下,只能抓到當頁的10筆,必須取消分頁 gv.DataBind(); DataTable dt = new DataTable(); DataColumn dc; DataRow dr; // 標題純文字這樣抓 //for (int i = 0; i < gv.Columns.Count; i++) //{ // dc = new DataColumn(); // dc.ColumnName = gv.Columns[i].HeaderText; // dt.Columns.Add(dc); //} // 標題純文字這樣抓 for (int i = 0; i < gv.HeaderRow.Cells.Count; i++) { dt.Columns.Add(gv.HeaderRow.Cells[i].Text.Replace(" ", "")); } // 抓資料 //for (int i = 0; i < gv.Rows.Count; i++) //{ // dr = dt.NewRow(); // for (int j = 0; j < gv.Columns.Count; j++) // { // dr[j] = gv.Rows[i].Cells[j].Text; // } // dt.Rows.Add(dr); //} foreach (GridViewRow row in gv.Rows) { DataRow datarow = dt.NewRow(); // 用 gv.Columns.Count 可能抓到 0,用 row.Cells.Count for (int i = 0; i < row.Cells.Count; i++) { datarow[i] = row.Cells[i].Text.Replace(" ", ""); } dt.Rows.Add(datarow); } gv.AllowSorting = true; gv.AllowPaging = true; gv.DataBind(); return dt; } |
(完)
沒有留言:
張貼留言