asp.net NPOI导出xlsx格式文件,打开文件报“Excel 已完成文件级验证和修复。此工作簿的某些部分可能已被修复或丢弃” HSSF,XSSF和SXSSF的区别 使用XSSFWork创建的xlsx后缀Excel文件无法打开

asp.net NPOI导出xlsx格式文件,打开文件报“Excel 已完成文件级验证和修复。此工作簿的某些部分可能已被修复或丢弃”

 

NPOI导出xlsx格式文件,会出现如下情况:

点击“是”:

 

导出代码如下:

复制代码
/// <summary>
        ///     将datatable数据写入excel并下载
        /// </summary>
        /// <param name="dt">datatable </param>
        /// <param name="excelName">文件名</param>
        /// <param name="templatePath">模板路径</param>
        /// <returns></returns>
        public static void DataTableToExcelAndDownload(DataTable dt, string excelName, string templatePath)
        {
            IWorkbook workbook = null;
            FileStream fs = null;
            IRow row = null;
            ISheet sheet = null;
            ICell cell = null;
            ICellStyle cellStyle = null;

            try
            {
                if (dt != null && dt.Rows.Count > 0)
                {
                    var rowCount = dt.Rows.Count; //行数
                    var columnCount = dt.Columns.Count; //列数

                    using (fs = File.OpenRead(templatePath))
                    {
                        //大批量数据导出的时候,需要注意这样的一个问题,Excel2003格式一个sheet只支持65536行,excel 2007 就比较多,是1048576
                        //workbook = new HSSFWorkbook(fs);//2003版本.xls
                        workbook = new XSSFWorkbook(fs); // 2007版本.xlsx
                    }

                    if (workbook != null)
                    {
                        sheet = workbook.GetSheetAt(0); //读取第一个sheet

                        //设置每行每列的单元格,
                        for (var i = 0; i < rowCount; i++)
                        {
                            row = sheet.CreateRow(i + 1);
                            for (var j = 0; j < columnCount; j++)
                            {
                                cell = row.CreateCell(j);
                                var value = dt.Rows[i][j];
                                var bdType = value.GetType().ToString();
                                switch (bdType)
                                {
                                    case "System.String":
                                        cell.SetCellValue(value.ToString());
                                        break;
                                    case "System.DateTime": //日期类型 
                                        cell.SetCellValue(
                                            Convert.ToDateTime(value.ToString()).ToString("yyyy-MM-dd HH:mm:ss"));
                                        break;
                                    case "System.Int16": //整型   
                                    case "System.Int32":
                                    case "System.Int64":
                                    case "System.Byte":
                                        var intV = 0;
                                        int.TryParse(value.ToString(), out intV);
                                        cell.SetCellValue(intV);
                                        break;
                                    case "System.Decimal": //浮点型   
                                    case "System.Double":
                                        double doubV = 0;
                                        double.TryParse(value.ToString(), out doubV);//格式化值
                                        cellStyle = workbook.CreateCellStyle();
                                        cellStyle.DataFormat = HSSFDataFormat.GetBuiltinFormat("0.00");
                                        cell.SetCellValue(doubV);
                                        cell.CellStyle = cellStyle;                                        
                                        break;
                                    default:
                                        cell.SetCellValue(value.ToString());
                                        break;
                                }
                            }
                        }

                        var context = HttpContext.Current;
                        context.Response.Clear();
                        context.Response.ContentType = "application/vnd.ms-excel";
                        context.Response.AppendHeader("Content-Disposition", "attachment; filename=" + excelName);
                        using (var ms = new MemoryStream())
                        {
                            workbook.Write(ms);

                            long fileSize = ms.Length;
                            //加上设置大小下载下来的.xlsx文件打开时才不会报“Excel 已完成文件级验证和修复。此工作簿的某些部分可能已被修复或丢弃”
                            context.Response.AddHeader("Content-Length", fileSize.ToString());

                            context.Response.BinaryWrite(ms.GetBuffer());
                            context.ApplicationInstance.CompleteRequest();
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                if (fs != null)
                {
                    fs.Close();
                }
                ExceptionHandling.ExceptionHandler.HandleException(ex);
            }
        }
复制代码

加上设置大小下载下来的.xlsx文件打开时才不会报“Excel 已完成文件级验证和修复。此工作簿的某些部分可能已被修复或丢弃”

long fileSize = ms.Length;
context.Response.AddHeader("Content-Length", fileSize.ToString());

即可。

 

 

HSSF,XSSF和SXSSF的区别

博客分类:
 
HSSF是POI工程对Excel 97(-2007)文件操作的纯Java实现 
XSSF是POI工程对Excel 2007 OOXML (.xlsx)文件操作的纯Java实现 

从POI 3.8版本开始,提供了一种基于XSSF的低内存占用的API----SXSSF 

SXSSF通过一个滑动窗口来限制访问Row的数量从而达到低内存占用的目录,XSSF可以访问所有行。旧的行数据不再出现在滑动窗口中并变得无法访问,与此同时写到磁盘上。 
在自动刷新的模式下,可以指定窗口中访问Row的数量,从而在内存中保持一定数量的Row。当达到这一数量时,在窗口中产生新的Row数据,并将低索引的数据从窗口中移动到磁盘中。 
或者,滑动窗口的行数可以设定成自动增长的。它可以根据需要周期的根据一次明确的flushRow(int keepRows)调用来进行修改。 

注意:针对 SXSSF Beta 3.8下,会有临时文件产生,比如: 
poi-sxssf-sheet4654655121378979321.xml 
文件位置:java.io.tmpdir这个环境变量下的位置 
Windows 7下是C:\Users\xxxxxAppData\Local\Temp 
Linux下是 /var/tmp/ 
要根据实际情况,看是否删除这些临时文件
 

官方也提供了一些解决方式: 
https://issues.apache.org/bugzilla/show_bug.cgi?id=53493 

与XSSF的对比 
在一个时间点上,只可以访问一定数量的数据 
不再支持Sheet.clone() 
不再支持公式的求值 



特性汇总 
 
 
 

这次需要自己写个自用的Excel导出工具:

照着POI的官方文档新建一个Excel文件。


Workbook wb = new XSSFWorkbook();
FileOutputStream fileOut = new FileOutputStream("workbook.xlsx");
wb.write(fileOut);
fileOut.close();

导出的xlsx后缀的Excel文件打开时,Office提示错误,发现“xxx.xlsx”中的部分内容有问题,是否让我们尽量尝试恢复,如果您信任此工作簿的源,请单击“是”。

但是点击了是之后发现提示,Microsoft Excel无法打开或修复此工作簿,因为它已损害。

 

搜索引擎查不到相关问题问题,文件写出导入了下载的POI里面的所有JAR包。

 

后面继续写了下去,往工作簿里插入了一张工作表:


Sheet sheet1 = wb.createSheet("new sheet");

然后xlsx文件正常打开了。


其实就是整个Excel文件格式的问题,虽然新建的工作簿,但是里面是一张工作表都没有的,而Office自己新建的时候会默认生成3张工作表,但是自己用编程创建的Excel,Office打开的时候便报错了。

官方文档这样一个New Workbook的介绍确实有点缺陷,应该对应说明。
---------------------
作者:iaiti
来源:CSDN
原文:https://blog.csdn.net/iaiti/article/details/45153627
版权声明:本文为博主原创文章,转载请附上博文链接!

 
 
 
 
 
 
 
 
https://zhidao.baidu.com/question/1449607222917334620.html
excel 的xlsx格式似乎修复不了这个问题,将文件后缀改为xls,再打开后选择修复。修复完成后另存为xlsx文件即可解决问题
今天遇到同样的问题,很幸运的解决了,在这里分享给大家,希望能帮到各位。
方法是下载WPS,用它打开文件,如果能够打开且保有之前的数据,那么就恭喜你啦!最后再保存为*.xslx文件就好~
 
1.点“是”,会弹出“通过修复或删除不可读取的内容,Excel已能够打开该文件。”。2.仔细看好此对话框标红色的部分,在 xl 文件夹下的sharedStrings.xml文件出问题了,下面还写了报错的代码行数。 (学过xml知识的应该会明白这是什么问题,没学过xml的也没关系,跟着我一步一步做下去。)3. 现在知道了哪个文件出了错,下一步呢,就是找到这个出错的文件。先把出错文件的文件扩展名(.xlsx)改成压缩文件(.zip)。如不显示扩展名,按此操作:打开我的电脑-〉按alt键显示工具栏-〉工具-〉文件夹选项-〉查看-〉去掉“隐藏已知的文件扩展名”前面的勾。)4. 双击zip文件(不是解压缩,只是双击文件来打开。)找到xl文件下的sharedStrings.xml文件并双击打开文件(一般已IE浏览器打开)。在IE浏览器上会显示错误PS: 如打开解压包时弹出错误框就表示文件损坏太大,这个就没办法了,没办法作下一步了。解压包这里还会提示“...是否替换原有的文件...”,选择“是”。最后把zip文件扩展名再改回原来的扩展名,即xlsx。双击打开文件。有提示的话点“是”,你的数据已恢复原样了。
posted @ 2018-10-19 18:47  ~雨落忧伤~  阅读(4386)  评论(0编辑  收藏  举报