16

EPPlus を使用していくつかの .XLSX ファイルを作成すると、奇妙な問題が発生します。パッケージを作成してから、応答に出力しています。

次のようにパッケージを作成しました。

var file = new FileInfo(@"C:\Test.xlsx");
ExcelPackage package = new ExcelPackage(file);
//...code to output data...//
package.Save();

これにより、ファイルがローカルの C: ドライブに正しく保存され、開くとうまく機能します。エラーなどはありません。フォーマットは正しいなどです。

ただし、このファイルを応答ストリームに出力したいので、コードを次のように変更しました。

ExcelPackage package = new ExcelPackage();
//...code to output data...//
MemoryStream result = new MemoryStream();
package.SaveAs(result);
context.Response.Clear();
context.Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";                                                       
context.Response.AddHeader("Content-Disposition", "attachment;filename=MissionDetails.xlsx");
result.WriteTo(context.Response.OutputStream);
context.Response.End(); 

しかし、このコードを実行すると、Excel ファイルを開こうとすると次のプロンプトが表示されます。

ファイル名.xlsx に読み取り不能なコンテンツが見つかりました。このブックの内容を復元しますか? このブックの発行元が信頼できる場合は、[はい] をクリックします。

[はい] をクリックすると、次のプロンプトが表示されます。

このファイルは、Microsoft Excel を使用して開くことはできません。ファイルを開くことができるコンバーターを Microsoft Office Online Web サイトで検索しますか?

ここで選択Noすると、Excel ファイルが開き、次のエラーが表示されます。

Excel はファイル レベルの検証と修復を完了しました。このブックの一部が修復または破棄された可能性があります。

しかし、ファイルは正常にロードされ、正しくフォーマットされているように見えます。しかし、ファイルを開こうとするたびに、同じプロンプトとエラー メッセージが表示されます。

注:データを出力するコードは、これらのいずれのシナリオでも変わりません。

誰もこのようなものを見たことがありますか?または、応答に出力するときにのみ、これがファイルを誤って保存する原因となる可能性があることを知っていますか?

4

5 に答える 5

17

私はこの問題の解決策を見つけました!予想どおり、ローカルに保存したときにファイルを開くことができましたが、応答を介してファイルを開くことができなかったため、応答と関係がありました。

ここでの問題は、例外がログに記録されて表示されていたtry..catchブロックにコードがラップされていたことです。

Response.End()を呼び出すと、System.Threading.ThreadAbortExceptionが発生することに気づきました。これが発生すると、エラーの出力がファイルの最後に追加されていたようです。

その特定の例外のエラーログを取り除いたとき、それはうまくいきました!

詳細については、この投稿を参照してくださいhttp://epplus.codeplex.com/discussions/223843?ProjectName=epplus

//...output code...//
catch(Exception ex){
    if (!(ex is System.Threading.ThreadAbortException))
    {
        //Log other errors here
    }
}
于 2012-07-19T15:29:47.823 に答える
8

あなたのリンクが「GetAsByteArray()」を呼び出していた私の問題を解決してくれたことに感謝します。以下とあなたが与えたリンクにリストされているようにすると、私は例外が追加されないようにします。いくつかの魔法で。

あなたは投票してください!

mrxrsd
Editor

Aug 17, 2010 at 12:30 PM


Call response.clear before send stream back to client.

                    Response.Clear();
                     Response.AddHeader("content-disposition", "attachment;  filename=file.xlsx");
                     Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";                   
                     Response.BinaryWrite(pck.GetAsByteArray());
                     Response.End();

http://epplus.codeplex.com/discussions/223843?ProjectName=epplus

于 2013-05-21T19:48:07.943 に答える
0

EPPlus を IE から開くことができませんでした。正常に保存され、エラーなしで開きました。(クロムは保存とオープンの両方で正常に機能しました)。ここでの提案は私にとってはうまくいきませんでした-最終的に私にとってうまくいったashxファイルではなく、aspxファイルを使用していた可能性があります。

何時間も検索した後、このstackoverflowの投稿に従ってashxファイルを使用することになり、EPPlusを使用して警告/破損ファイルメッセージなしですべてのブラウザーで動作するようになりました.

他の人に役立つ追加リソース:

これで他の誰かの時間を節約できることを願っています。

于 2014-03-21T05:02:25.750 に答える
0

[Excel にエクスポート] ボタンをクリックしたときの page.aspx.cs コード

string templateFileName = Server.MapPath("~/ReportingTemplate/test.xlsx");
                System.IO.FileInfo templateFile = new System.IO.FileInfo(templateFileName);

                String message = ExcelPackagePlusLibrary.EPPlus.ExportToExcel(templateFile, dt, false, exportFileName, Response, "Data", "Summary", "Please type the client name here");
                if (String.IsNullOrEmpty(message) == false)
                {
                    /* Exception occur. */
                }
                dt.Clear();
///////////////////////////////////////////////////////////////////////////////////////

    /// <summary>
            /// ExportToExcel is a method used for Export To Excel with template file.
            ///
            /// </summary>
            /// <param name="templateFile">The fully qualified name of the new file, or the relative file name. Do not end the path with the directory separator character.</param>
            /// <param name="dt">Datatable for export.</param>
            /// <param name="printHeaders">Datatable's header used or not, when Export it. </param>
            /// <param name="exportFileName">provide fileName only not path. </param>
            /// <param name="Response">System.Web.HttpResponse. </param>
            /// <param name="sheetNames">arg[0] means provide sheet name where you want to load data. \n (Optional Parameter) arg[1] means provide sheet name where you want to edit. (Optional Parameter) arg[2] means if your intention is to Edit sheet so provide searchText.</param>
            /// 
            public static string ExportToExcel(FileInfo templateFile, DataTable dt, bool printHeaders, string exportFileName, System.Web.HttpResponse Response, params String[] sheetNames)
            {
                try
                {
                    using (ExcelPackage p = new ExcelPackage(templateFile, false))
                    {
                        EPPlus.AddSheetWithTemplate(p, dt, sheetNames[0], printHeaders);


                        String[] clientName = exportFileName.Split(new char[] { '_' }, 2);

                        if (sheetNames.Count() > 2)
                        {
                            ExcelPackagePlusLibrary.EPPlus.EditSheet(p, sheetNames[1], sheetNames[2], clientName[0] ?? exportFileName);
                        }

                        Byte[] fileBytes = p.GetAsByteArray(); //Read the Excel file in a byte array

                        //Clear the response
                        Response.ClearHeaders();
                        Response.ClearContent();
                        Response.Clear();

                        //Response.Cookies.Clear();


                        //Add the header & other information
                        //Response.Cache.SetCacheability(System.Web.HttpCacheability.Private);
                        //Response.CacheControl = "private";
                        //Response.Charset = System.Text.UTF8Encoding.UTF8.WebName;
                        //Response.ContentEncoding = System.Text.UTF8Encoding.UTF8;
                        //Response.AppendHeader("Content-Length", fileBytes.Length.ToString());
                        //Response.AppendHeader("Pragma", "cache");
                        //Response.AppendHeader("Expires", "60");
                        Response.AddHeader("Content-Disposition",
                        "attachment; " +
                        "filename=" + exportFileName + "; " +
                        "size=" + fileBytes.Length.ToString() + "; " +
                        "creation-date=" + DateTime.Now.ToString("R").Replace(",", "") + "; " +
                        "modification-date=" + DateTime.Now.ToString("R").Replace(",", "") + "; " +
                        "read-date=" + DateTime.Now.ToString("R").Replace(",", ""));

                        //Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
                        Response.ContentType = "application/x-msexcel";

                        //Write it back to the client
                        Response.BinaryWrite(fileBytes);
                        Response.Flush();
                        Response.Close();

                        /* Download to Client Side. */
                        //DirectoryInfo dir = new DirectoryInfo(Server.MapPath("~/Testing/Downloaded/" + DateTime.Now.ToString("MM-dd-yyyy")));
                        //if (!dir.Exists)
                        //{
                        //    dir.Create();
                        //}
                        //File.WriteAllBytes(dir.FullName + "\\" + fileName, fileBytes);

                        return String.Empty;
                    }
                }
                catch (Exception ex)
                {
                    _ErrorMessage = ex.Message.ToString();
                    return _ErrorMessage;
                }
            }
于 2012-08-24T09:12:19.977 に答える
0

WriteToメソッドの代わりに、これを試してください:

context.Response.BinaryWrite(package.GetAsByteArray());
于 2012-07-18T20:19:32.597 に答える