silverlight客户端保存文件乱码问题

时间:2021-12-13 15:50:22

最近做一个项目,有一个需求是这样的:服务端从数据库里获得数据,客户端保存为Excel文件  

    最初解决方案:服务端获得数据,通过ExcelPackage,Convert.ToBase64String将byte转化成string方式传输给客户端,客户端通过Convert.FromBase64String(excelData)将string转换为byte写入Excel文件,代码如下:

服务端:

public string GetExcelDataString(string connectionString, string sql)
{
    MemoryStream s = new MemoryStream();
    using (ExcelPackage pck = new ExcelPackage())
    {
        DataTable table = GetTableBySql(connectionString, sql);
        table.TableName = "ExprotData";
        ExcelWorksheet ws = pck.Workbook.Worksheets.Add(table.TableName);
        ws.Cells["A1"].LoadFromDataTable(table, true);
        pck.SaveAs(s);
    }
    return Convert.ToBase64String(s.ToArray());
}

 客户端:

using (Stream fs = (Stream)SaveFileDialog.OpenFile())
{
    byte[] fileBytes = Convert.FromBase64String(excelDataString);
    fs.Write(fileBytes, 0, fileBytes.Length);
    fs.Close();
}

这样可以实现上面需求,但是存在一个问题:在数据量特别大的时候占用内存较大,还有一个问题是,时间字段传输过来保存后是一个五位的数字串,得不到时间,这样就需要进行优化。
注意:silverlight保存文件时,不允许通过打开制定路径方式保存,必须通过SaveFileDialog类来实现;

新的解决方案如下:服务端将datatable转换为string,客户端解析string,并写入excel文件

服务端:

public string GetExcelAsString(string connectionString, string sql)
{
    MemoryStream s = new MemoryStream();
    DataTable table = GetTableBySql(connectionString, sql);
    var result = DataTableToCsv(table);
    return result;
}

 

public string DataTableToCsv(DataTable table)
{
    var result = new StringBuilder();
    for (int i = 0; i < table.Columns.Count; i++)
    {
        result.Append(table.Columns[i].ColumnName);
        result.Append(i == table.Columns.Count - 1 ? "\n" : ",");
    }
    foreach (DataRow row in table.Rows)
    {
        for (int i = 0; i < table.Columns.Count; i++)
        {
            result.Append("\"" + row[i].ToString().Replace("\"", "\"\"") + "\"");
            result.Append(i == table.Columns.Count - 1 ? "\n" : ",");
        }
    }
    return result.ToString();
}

客户端:

using (Stream fs = (Stream)SaveFileDialog.OpenFile())
{
    StreamWriter sw = new StreamWriter(fs, Encoding.UTF8);
    sw.WriteLine(excelData);
    sw.Flush();
    sw.Close();
    fs.Close();
}

这样就可以解决传输数据量过大和写入文件乱码问题。
总结:受第一种解决方案的影响,在优化时一直想着把string转换为bytes,然后在通过fs.Write(fileBytes, 0, fileBytes.Length)写入文件,这样就有一个问题,无论怎么转换,最终写入文件的中文字符都是乱码,尝试一个下午依然无法实现。最后查找一些其他资料,发现这个问题饶了一个大的圈子,最后通过方案二解决。大家在做事情时一定不要受思维定式影响,有时其实解决方案很简单,不要想得那么复杂。

silverlight不支持ASCIIEncoding.GetEncoding("GB2312").GetBytes(stringData)这种方式转换,没有ASCIIEncoding的解码方式;

silverlight通过byte[] fileBytes = UTF8Encoding.UTF8.GetBytes(stringData);转换后写入文件,依然乱码,但是不转换为bytes,直接用StreamWriter的UTF8问题解决;