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;
}
|
(完)
沒有留言:
張貼留言