将 XLSM 文件保存到数据库列并检索?

发布于 2024-07-23 22:39:41 字数 1547 浏览 4 评论 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;
            }
        }

The code previously implemented takes in the xls file saves it on to a column in a table using the stream i use the same method but the only change is the the file saved is a xlsm or an xlsx type file it saves to the column in the database

When I try and get the contents from the database and throw the saved xlsm file or xlsx file I get an error "Excel file found unreadable content do you want to recover the contents of this work book ?"

Here's the code to save the xlsm or the xlsx file

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();

To retrieve and send to user

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;
            }
        }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

陌上芳菲 2024-07-30 22:39:41

我忍不住注意到代码未能将 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;
                }
            }
        }
    }
}

I couldn't help but notice the number of places where your code failed to wrap an IDisposable in a using block, like the following:

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;
                }
            }
        }
    }
}
放手` 2024-07-30 22:39:41

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

首先,您没有调用reader.Read()。

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

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

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

A couple of things strike me as possibilities.

Firstly, you are not calling reader.Read().

Secondly, there is not need for the check on retval == bufferSize - just call GetBytes again and it will return 0 if no bytes were read from the field.

Thirdly, as you are writing to the HttpResponse you need to make sure that you call Response.Clear() before writing the bytes to the output, and Response.End() after writing the file to the response.

The other thing to try is saving the file to the hard drive and comparing it to the original. Is it the same size? If it is bigger then you are writing too much information to the file (see previous comments about HttpResponse). If it is smaller then you are not writing enough, and are most likely exiting the loop too soon (see comment about retval).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文