iT邦幫忙

0

(已解決)C# NPOI 產生xlsx後開啟有錯誤訊息

請教一下各位,我利用NPOI產生一個.xlsx的檔案匯出,用Excel開啟都會提示有部分內容有問題,要嘗試修復,是否信任這個活頁部的來源。
按下是之後,雖然有正常打開,但是會有下列訊息 "Excel 已完成檔案層級的驗證和修復。此活頁簿的某些部分可能已經修復或遺失。"
https://ithelp.ithome.com.tw/upload/images/20211116/20134928IifvXMkVzu.jpg
excel 的版本是2019標準版

以下是我的部分程式碼

public void WriteExcelWithNPOI(string extension, string filename, DataTable dt)
{
    IWorkbook workbook;

    if (extension == "xlsx")
    {
        workbook = new XSSFWorkbook();
    }
    else if (extension == "xls")
    {
        workbook = new HSSFWorkbook();
    }
    else
    {
        throw new Exception("This format is not supported");
    }

    ISheet sheet1 = workbook.CreateSheet(filename);

    IRow row1 = sheet1.CreateRow(0);
    for (int j = 0; j < dt.Columns.Count; j++)
    {
        ICell cell = row1.CreateCell(j);

        String columnName = dt.Columns[j].ToString();
        cell.SetCellValue(columnName);
    }
    for (int i = 0; i < dt.Rows.Count; i++)
    {
        IRow row = sheet1.CreateRow(i + 1);
        for (int j = 0; j < dt.Columns.Count; j++)
        {
            ICell cell = row.CreateCell(j);
            String columnName = dt.Columns[j].ToString();
            if (j == 0)
            {
                cell.SetCellValue(DateTime.Parse(dt.Rows[i][columnName].ToString()).ToString("yyyy/MM/dd").Trim());
            }
            else
            {
                cell.SetCellValue(dt.Rows[i][columnName].ToString().Trim());
            }

        }

    }
   
    var context = HttpContext.Current;
    context.Response.Clear();
    context.Response.ContentType = "application/vnd.ms-excel";
    context.Response.AppendHeader("Content-Disposition", "attachment; filename=\"" + filename + "\"");
    using (var ms = new MemoryStream())
    {
        workbook.Write(ms);
        
        context.Response.AddHeader("Content-Length", (ms.ToArray().Length).ToString());
        context.Response.BinaryWrite(ms.GetBuffer());
        context.ApplicationInstance.CompleteRequest();
        context.Response.Output.Flush();
    }
    
    }
看更多先前的討論...收起先前的討論...
天黑 iT邦研究生 5 級 ‧ 2021-11-16 15:30:01 檢舉
上面那段其實我完全沒看到NPOI相關的部分.... 如果對產出的檔案有疑問 應該是先直接存檔 確認打開是不是一樣的問題
fillano iT邦超人 1 級 ‧ 2021-11-16 17:11:39 檢舉
如果是content-length錯誤導致下載不完全,因為xlsx是個zip archive,你可以用解壓縮軟體開開看是否有問題。
fillano iT邦超人 1 級 ‧ 2021-11-16 17:17:17 檢舉
ms.ToArray().Length).ToString()是檔案長度?那你的fileSize(或是ms.Length)是什麼?
@fillano fileSize是之前參考別人的程式碼忘記拿掉了已更新貼文,想請教一下您說的用解壓縮軟體開是甚麼意思? xlsx再解壓縮是一些xml檔,不太懂怎麼看
水無痕 iT邦新手 3 級 ‧ 2021-11-17 09:25:42 檢舉
先試一件事,直接寫在 server 端,不要經過 Response,開啟檔案看看會不會有 "某些部分可能已經修復或遺失" 的訊息。如果有,才能確定是 NPOI 的問題,如果沒有,就要朝 Response 方向調整 !
感謝樓上,我直接用filestream寫到本機實體位置的xlsx打開就就沒有錯誤訊息。不過Response調整很多都一樣有錯誤訊息,非常感謝,給我一個方向去找問題
建議改學EPPLUS
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 個回答

4
hsumingw
iT邦新手 5 級 ‧ 2021-11-17 11:24:12
最佳解答

MemoryStream 的 GetBuffer 會傳回整個記憶組,包含未使用的。所以 Excel 檔後有一堆 null 位元,造成開啟時判斷為壞檔。試試直接寫入 OutputStream

Response.Clear();
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.AddHeader("Content-Disposition", string.Format("attachment; filename={0}", saveAsFileName));
workbook.Write(Response.OutputStream);
Response.Flush();
Response.Close();

原來如此,照著用就解決問題了,非常感謝您

0
talijoy
iT邦見習生 ‧ 2022-10-06 17:18:56

其實你只是少了一個context.Response.Close();
如下:
context.Response.Output.Flush();
context.Response.Close(); //<--這行

我要發表回答

立即登入回答