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

可能性としていくつかのことが思い浮かびます。

まず、あなたは電話していませんreader.Read()

次に、チェックをオンにする必要はありませんretval == bufferSize。フィールドからバイトが読み取られなかった場合は、GetBytes をもう一度呼び出すだけで 0 が返されます。

第 3 に、HttpResponse に書き込んでいるので、バイトを出力に書き込む前に Response.Clear() を呼び出し、ファイルを応答に書き込んだ後に Response.End() を呼び出す必要があります。

もう 1 つは、ファイルをハード ドライブに保存し、元のファイルと比較することです。同じサイズですか?それより大きい場合は、ファイルに書き込んでいる情報が多すぎます (HttpResponse に関する以前のコメントを参照してください)。小さい場合は、十分に書き込んでおらず、おそらくループをすぐに終了している可能性があります ( についてのコメントを参照してくださいretval)。

于 2009-06-09T10:45:53.730 に答える
0

using次のように、コードが IDisposable をブロックにラップできなかった場所の数に気付きました。

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 に答える