Add UTF-8 Signature(BOM) at the Start of Response File

By | January 31, 2011

In ASP.Net, if you write a file to the client using code like this:

HttpContext.Current.Response.Clear();
HttpContext.Current.Response.AddHeader( "content-disposition", string.Format( "attachment; filename={0}", fileName ) );
HttpContext.Current.Response.ContentType = "application/ms-excel";

using( StringWriter sw = new StringWriter() )
{
    using( HtmlTextWriter htw = new HtmlTextWriter( sw ) )
    {
        //  Create a form to contain the grid
        Table table = new Table();

        //  render the table into the htmlwriter
        table.RenderControl( htw );

        //  render the htmlwriter into the response
        HttpContext.Current.Response.Write( sw.ToString() );

        HttpContext.Current.Response.End();

    }
}

My situation is to render a table to a file named xxx.xls(Excel file) and send to the client. And the file contains Chinese or other languages, it may cause some error codes in the file. This could happen randomly, sometimes error codes sometimes not.

After trying, I found if you save the file to UTF-8 with Signature, the error codes gone.

Then I tried to add the BOM the file before sending to the client:

HttpContext.Current.Response.Clear();
HttpContext.Current.Response.AddHeader( "content-disposition", string.Format( "attachment; filename={0}", fileName ) );
HttpContext.Current.Response.ContentType = "application/ms-excel;charset=UTF-8;";

//prepare a memory stream
MemoryStream ms = new MemoryStream();

using( StreamWriter sw = new StreamWriter( ms ) )
{
    using( HtmlTextWriter htw = new HtmlTextWriter( sw ) )
    {
        //  Create a form to contain the grid
        Table table = new Table();

        //process your table here

        //  render the table into the htmlwriter
        table.RenderControl( htw );
        
        //remember to flush
        htw.Flush();

        //add the BOM
        byte[] bBOM = new byte[] { 0xEF, 0xBB, 0xBF };
        byte[] bContent = ms.ToArray();
        byte[] bToWrite = new byte[bBOM.Length + bContent.Length];

        //combile the BOM and the content
        bBOM.CopyTo( bToWrite, 0 );
        bContent.CopyTo( bToWrite, bBOM.Length );

        //write to the client
        HttpContext.Current.Response.Write( Encoding.UTF8.GetString( bToWrite ) );
        HttpContext.Current.Response.Flush();
        HttpContext.Current.Response.End();

        ms.Dispose();
    }
}

The file being rendered will be added the BOM at the beginning.