DataGrid数据导出excel文件,有时出现乱码解决方法。

来源:互联网 发布:vscode c 生成exe 编辑:程序博客网 时间:2024/05/02 02:10

以前是用Response.Write()方法直接将DataGrid内容输出到文件,但有时会出现excel文件里的中文全是乱码。

解决办法:

先将excel文件写到服务器上,然后再下载到客户端。

以下是代码片段:


private void Export(System.Web.UI.WebControls.DataGrid dg,string fileName,string typeName)
{

System.Web.HttpResponse httpResponse = Page.Response;
httpResponse.AppendHeader("Content-Disposition","attachment;filename="+HttpUtility.UrlEncode(fileName,System.Text.Encoding.UTF8));
httpResponse.ContentEncoding=System.Text.Encoding.GetEncoding("GB2312");
httpResponse.ContentType = typeName;
System.IO.StringWriter  tw = new System.IO.StringWriter() ;
System.Web.UI.HtmlTextWriter hw = new System.Web.UI.HtmlTextWriter (tw);
dg.RenderControl(hw);
string filePath = Server.MapPath("..")+fileName;
System.IO.StreamWriter sw = System.IO.File.CreateText(filePath);
sw.Write(tw.ToString());
sw.Close();

DownFile(httpResponse,fileName,filePath);
httpResponse.End();
}

private  bool DownFile(System.Web.HttpResponse Response,string fileName,string fullPath)
{
try
{
Response.ContentType = "application/octet-stream";

Response.AppendHeader("Content-Disposition","attachment;filename=" +
HttpUtility.UrlEncode(fileName,System.Text.Encoding.UTF8) + ";charset=GB2312");
System.IO.FileStream fs= System.IO.File.OpenRead(fullPath);
long fLen=fs.Length;
int size=102400;//每100K同时下载数据
byte[] readData = new byte[size];//指定缓冲区的大小
if(size>fLen)size=Convert.ToInt32(fLen);
long fPos=0;
bool isEnd=false;
while (!isEnd)
{
if((fPos+size)>fLen)
{
size=Convert.ToInt32(fLen-fPos);
readData = new byte[size];
isEnd=true;
}
fs.Read(readData, 0, size);//读入一个压缩块
Response.BinaryWrite(readData);
fPos+=size;
}
fs.Close();
System.IO.File.Delete(fullPath);
return true;
}
catch
{
return false;
}
}


private void btnWord_Click(object sender, System.EventArgs e)
{
Export(dataGrid,"FileName.doc","application/ms-word");//导出至Wrod

}

private void btnExcel_Click(object sender, System.EventArgs e)
{
Export(dataGrid,"FileName.xls","application/ms-excel");//导出至Excel
}

上面的是C#版本。下面贴出VB.net版本的,方便大家使用:

 Private Function Export(ByVal dg As System.Web.UI.WebControls.DataGrid, ByVal fileName As String, ByVal typeName As String) As Boolean
        Dim httpResponse As System.Web.HttpResponse = Page.Response
        httpResponse.AppendHeader("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode(fileName, System.Text.Encoding.UTF8))
        httpResponse.ContentEncoding = System.Text.Encoding.GetEncoding("GB2312")
        httpResponse.ContentType = typeName
        Dim tw As System.IO.StringWriter = New System.IO.StringWriter
        Dim hw As System.Web.UI.HtmlTextWriter = New System.Web.UI.HtmlTextWriter(tw)
        dg.RenderControl(hw)
        Dim filePath As String = Server.MapPath("..") + fileName
        Dim sw As System.IO.StreamWriter = System.IO.File.CreateText(filePath)
        sw.Write(tw.ToString())
        sw.Close()

        DownFile(httpResponse, fileName, filePath)
        httpResponse.End()
        Return True
    End Function
    Private Function DownFile(ByVal Response As System.Web.HttpResponse, ByVal fileName As String, ByVal fullPath As String) As Boolean
        Try
            Response.ContentType = "application/octet-stream"
            Response.AppendHeader("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode(fileName, System.Text.Encoding.UTF8) + ";charset=GB2312")
            Dim fs As System.IO.FileStream = System.IO.File.OpenRead(fullPath)
            Dim fLen As Long = fs.Length
            Dim size As Integer = 102400 '//每100K同时下载数据
            Dim readData() As Byte
            ReDim readData(size) '//指定缓冲区的大小
            If (size > fLen) Then
                size = Convert.ToInt32(fLen)
            End If
            Dim fPos As Long = 0
            Dim isEnd As Boolean = False
            While (Not isEnd)
                If ((fPos + size) > fLen) Then
                    size = Convert.ToInt32(fLen - fPos)
                    ReDim readData(size)
                    isEnd = True
                End If
                fs.Read(readData, 0, size) '//读入一个压缩块
                Response.BinaryWrite(readData)
                fPos += size
            End While
            fs.Close()
            System.IO.File.Delete(fullPath)
            Return True
        Catch
            Return False
        End Try
    End Function

Protected Sub btnWord_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnWord.Click
        Export(Me.DataGrid1, "FileName.doc", "application/ms-word")   '导出至Wrod
End Sub

Protected Sub btnExcel_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnExcel.Click
        Export(Me.DataGrid1, "FileName.xls", "application/ms-excel")   '导出至Excel
End Sub

原创粉丝点击