参考如下代码:
using System.IO;public void XlsWriteCellLabel(Stream AStream,
    int ACol, int ARow, string AValue)
{
    if (AStream == null) return;
    byte[] vValue = Encoding.Default.GetBytes(AValue);
    ushort[] vXlsLabel = { 0x0204, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 };
    vXlsLabel[1] = (ushort)(8 + vValue.Length);
    vXlsLabel[2] = (ushort)ARow;
    vXlsLabel[3] = (ushort)ACol;
    vXlsLabel[5] = (ushort)vValue.Length;
    byte[] vBuffer = new byte[vXlsLabel.Length * sizeof(ushort)];
    Buffer.BlockCopy(vXlsLabel, 0, vBuffer, 0, vBuffer.Length);
    AStream.Write(vBuffer, 0, vBuffer.Length);
    AStream.Write(vValue, 0, vValue.Length);
}public bool DataGridViewToExcel(DataGridView AGrid, string AFileName)
{
    if (AGrid == null) return false;
    if (!File.Exists(AFileName)) return false;
    FileStream vFileStream = new FileStream(AFileName,  
        FileMode.Create, FileAccess.Write);
    byte[] vXlsBof = { 0x09, 0x08, 0x08, 0x00, 0x00, 0x00, 0x10, 
        0x00, 0x00, 0x00, 0x00, 0x00 };
    byte[] vXlsEof = { 0x0A, 0x00, 0x00, 0x00 };    try
    {
        vFileStream.Write(vXlsBof, 0, vXlsBof.Length);
        int vEmptyRow = 1; // 空行数,空行不用添加
        if (AGrid.RowCount > 0)
            for (int i = 0; i < AGrid.ColumnCount; i++)
            {
                if (AGrid[i, AGrid.RowCount - 1].Value != null)
                {
                    vEmptyRow = 0;
                    break;
                }
            }        for (int i = 0; i < AGrid.ColumnCount; i++)
            for (int j = 0; j < AGrid.RowCount - vEmptyRow; j++)
            {
                XlsWriteCellLabel(vFileStream, i, j, 
                    string.Empty + AGrid[i, j].Value);
            }
        vFileStream.Write(vXlsEof, 0, vXlsEof.Length);
        vFileStream.Close();
    }
    finally
    {
        vFileStream.Dispose();
    }
    return true;
}