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());
即可。
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
版权声明:本文为博主原创文章,转载请附上博文链接!
方法是下载WPS,用它打开文件,如果能够打开且保有之前的数据,那么就恭喜你啦!最后再保存为*.xslx文件就好~


浙公网安备 33010602011771号