0

之前实现的代码在 xls 文件中使用流将其保存到表中的列中,我使用相同的方法,但唯一的变化是保存的文件是 xlsm 或 xlsx 类型的文件,它保存到列中数据库

当我尝试从数据库中获取内容并抛出保存的 xlsm 文件或 xlsx 文件时,我收到错误消息“Excel 文件发现无法读取的内容是否要恢复此工作簿的内容?”

这是保存 xlsm 或 xlsx 文件的代码

System.IO.Stream filestream = System.IO.File.Open(file, System.IO.FileMode.Open);
int fileLength = (int)filestream.Length;
byte[] input = new byte[fileLength];
filestream.Read(input, 0, fileLength);
string Sql = "insert into upload values(@contents)";
con.Open();
System.Data.SqlClient.SqlCommand c = new System.Data.SqlClient.SqlCommand(Sql, con);
c.Parameters.Add("@contents", System.Data.SqlDbType.Binary);
c.Parameters["@contents"].Value = input;
c.ExecuteNonQuery();

检索并发送给用户

SqlCommand comm = new SqlCommand("select contents from upload order by id desc", con);
SqlDataReader reader = comm.ExecuteReader();
int bufferSize = 32768;                   
        byte[] outbyte = new byte[bufferSize];  
        long retval;                           
        long startIndex = 0;                    
        startIndex = 0;
        retval = reader.GetBytes(0, startIndex, outbyte, 0, bufferSize);
        while (retval > 0)
        {
            System.Web.HttpContext.Current.Response.BinaryWrite(outbyte);
            startIndex += bufferSize;
            if (retval == bufferSize)
            {
                retval = reader.GetBytes(2, startIndex, outbyte, 0, bufferSize);
            }
            else
            {
                retval = 0;
            }
        }
4

2 回答 2

0

我不禁注意到您的代码未能将 IDisposable 包装在using块中的位置数量,如下所示:

using (SqlConnection con = new SqlConnection(connectionString))
{
    byte[] input;
    using (System.IO.Stream filestream = System.IO.File.Open(file, System.IO.FileMode.Open))
    {
        int fileLength = (int)filestream.Length;
        input = new byte[fileLength];
        filestream.Read(input, 0, fileLength);
    }
    const string Sql = "insert into upload values(@contents)";
    con.Open();
    using (System.Data.SqlClient.SqlCommand c = new System.Data.SqlClient.SqlCommand(Sql, con))
    {
        c.Parameters.Add("@contents", System.Data.SqlDbType.Binary);
        c.Parameters["@contents"].Value = input;
        c.ExecuteNonQuery();
    }

    using (SqlCommand comm = new SqlCommand("select contents from upload order by id desc", con))
    {
        using (SqlDataReader reader = comm.ExecuteReader())
        {
            int bufferSize = 32768;
            byte[] outbyte = new byte[bufferSize];
            long retval;
            long startIndex = 0;
            startIndex = 0;
            retval = reader.GetBytes(0, startIndex, outbyte, 0, bufferSize);
            while (retval > 0)
            {
                System.Web.HttpContext.Current.Response.BinaryWrite(outbyte);
                startIndex += bufferSize;
                if (retval == bufferSize)
                {
                    retval = reader.GetBytes(2, startIndex, outbyte, 0, bufferSize);
                }
                else
                {
                    retval = 0;
                }
            }
        }
    }
}
于 2009-07-17T12:20:06.633 回答
0

有几件事让我觉得有可能。

首先,你没有打电话reader.Read()

其次,不需要检查retval == bufferSize- 只需再次调用 GetBytes,如果没有从字段中读取任何字节,它将返回 0。

第三,当您写入 HttpResponse 时,您需要确保在将字节写入输出之前调用 Response.Clear() ,并在将文件写入响应之后调用 Response.End() 。

要尝试的另一件事是将文件保存到硬盘驱动器并将其与原始文件进行比较。大小一样吗?如果它更大,那么您将太多信息写入文件(请参阅之前关于 HttpResponse 的评论)。如果它更小,则说明您写得不够多,并且很可能过早退出循环(请参阅关于 的评论retval)。

于 2009-06-09T10:45:53.730 回答