iT邦幫忙

0

[c#] web GridView/DataGrid(RenderControl)轉成EXCEL & 頁面輸出 (Response.AppendHeader)

  • 分享至 

  • xImage
  •  

這篇本來只是單純的網頁匯出EXCEL
但因為遇到了匯出的內容亂碼,異外的認識了BOM的故事.
匯出很簡單,就是用....
但是在匯出的時侯,沒有BOM的檔案,會讓EXCEL不知道要用utf8來解析它,所以EXCEL呈現亂碼了.(疑?那它用什麼解析的呢?

GridView

不知道為什麼只導出GridView,但整個頁面都輸出了.所以只好把不要的區塊visible=false

public void ExportToEXCEL(System.Web.UI.WebControls.GridView gv, string filename, string headtxt)
{
this.dgShow.AllowPaging = false;
this.dgShow.EnableViewState = false; //把ViewState給關了
this.dgShow.DataBind();
plQuery.Visible = false;

        Response.Buffer = true;
        Response.Charset = "UTF-8"; //設定字集
        Response.AppendHeader("Content-Disposition", "attachment;filename=xxx.xls"); //filename 可自定
        Response.ContentEncoding = System.Text.Encoding.GetEncoding("UTF-8");
        Response.ContentType = "application/ms-excel "; //內容型態設為Excel
        
        System.IO.StringWriter objStringWriter = new System.IO.StringWriter();
        System.Web.UI.HtmlTextWriter objHtmlTextWriter = new System.Web.UI.HtmlTextWriter(objStringWriter);
        //this.RenderControl(objHtmlTextWriter); 
        this.dgShow.RenderControl(objHtmlTextWriter);
        //不知道為什麼只導出dgshow,但整個頁面都輸出了.所以只好把不要的區塊visible=false
        Response.Write(objStringWriter.ToString());
        Response.End();

        this.dgShow.AllowPaging = true;
        this.dgShow.EnableViewState = true; //把ViewState
        this.dgShow.DataBind();
        plQuery.Visible = true;
    } 
    public override void VerifyRenderingInServerForm(Control control)
    { 
        // '處理'GridView' 的控制項 'GridView' 必須置於有 runat=server 的表單標記之中  
    }

DataGrid

Response.ClearContent();
Response.Clear();
Response.Buffer=true;
Response.Charset ="UTF-8"; //設定字集
Response.ContentEncoding = System.Text.Encoding.UTF8;//表格內容新增編碼格式

    string sFilename = HttpUtility.UrlEncode("中文", System.Text.Encoding.UTF8);//處理中文檔名亂碼        
    Response.AppendHeader("Content-Disposition","attachment;filename="+sFilename+".xls"); 

    Response.ContentType = "application/ms-excel "; //內容型態設為Excel 
    this.EnableViewState = false; //把ViewState給關了
    System.IO.StringWriter objStringWriter = new  System.IO.StringWriter();
    System.Web.UI.HtmlTextWriter objHtmlTextWriter = new System.Web.UI.HtmlTextWriter(objStringWriter);

    this.DataGrid1.RenderControl(objHtmlTextWriter);  //get畫面上的資料

    System.IO.StreamWriter sw =	new System.IO.StreamWriter(	Response.OutputStream,System.Text.Encoding.UTF8);//這樣一筆的時侯,就不會亂碼了
    sw.Write(objStringWriter.ToString());
    sw.Close(); 

    Response.End();

QA 匯出的EXCEL亂碼

 匯出的EXCEL檔案,如果很多筆,OK.但如果只有一筆,就會有中文亂碼的情況
 解決方法,使用stream寫入,且指定UFT8.就可以了.
 ref
 https://blog.darkthread.net/blog/csv-encoding-again/

Q什麼BOM不BOM的,到底是什麼東西?看的到嗎?

BOM
位元組順序記號(英語:byte-order mark,BOM)是位於碼點U+FEFF的統一碼字元的名稱。當以UTF-16或UTF-32來將UCS/統一碼字元所組成的字串編碼時,這個字元被用來標示其位元組序。它常被用來當做標示檔案是以UTF-8、UTF-16或UTF-32編碼的記號。資料擷取自維基百科
哈.有聽沒有懂.

目前已知

軟體 BOM 沒BOM
記事本 OK OK
EXCEL OK 亂碼
狀態 File.WriteAllText StreamWriter memo
沒指定 沒BOM 沒BOM File.WriteAllText("B:\F1.csv", '中文');
指定但不想有BOM -- -- new StreamWriter (strPath,false,utf8);
指定 有BOM 有BOM File.WriteAllText("B:\F1.csv", '中文', Encoding.UTF8);

ref
https://blog.darkthread.net/blog/write-utf8-file-with-bom/

class about BOM about Encoding
StreamWriter 寫的時侯, 會把BOM加進來 預設會先自動判斷檔案編碼,無法確認才會使用設定的編碼
StreamReader 讀的時侯, 會把BOM自動濾掉

Windows 作業系統不少程式(像是記事本),預設會對 UTF-8 檔案加上 BOM
而 Linux 則避免妨礙到像是解譯器腳本而不加 BOM,對於沒有預期要處理 BOM 的 Linux 程式而言,會造成讀取錯誤,這也是跨平台常遇到的事情之一。6

StreamReader 預設會先自動判斷檔案編碼,無法確認才會使用設定的編碼。
所以如果不需要BOM的話,不指定也沒關係.

ref
https://twblog.hongjianching.com/2017/12/17/why-csharp-write-and-read-file-with-different-encoding-but-success/

寫的好清楚-BE與LE的差別

先介紹3種編碼,介紹的好清楚.
再介紹為什麼需要BOM.
再介紹萬惡的BOM是怎麼回事.
https://ignatius1895.pixnet.net/blog/post/71034743-%E5%AD%97%E5%85%83%E7%B7%A8%E7%A2%BC%E8%88%87%E7%A8%8B%E5%BC%8F%E8%A8%AD%E8%A8%88%28%E4%BA%94%29%EF%BC%9Aunicode%E7%9A%84%E7%B7%A8%E7%A2%BC


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言