关于"发现*.xlsx中部分内容有问题,是否让我们尽量尝试恢复?如果您信任此工作簿的源,请单击"是""的解决方案。
关于这个问题,我给出的解决方案是针对使用C#中MemoryStream流写入文件的方法,首先贴出利用NPOI.XSSF中XSSFWorkbook生成excel文件的代码:
public class Excel
{
/// <summary>
/// 生成EXCEL文件(.xlsx)
/// </summary>
/// <param name="data">待保存的数据</param>
/// <param name="header">表头,为空时则无表头</param>
/// <returns></returns>
public static XSSFWorkbook GenerateXLSX(IList<List<string>> data, IList<string> header = null, string author = null, string sheetName = "Sheet1")
{
XSSFWorkbook xlsx = new XSSFWorkbook();
ISheet sheet = xlsx.CreateSheet(sheetName);
Int32 rowID = 0;
// 创建表头
if (header != null && 0 < header.Count)
{
IRow row = sheet.CreateRow(rowID);
for (Int32 col = 0; col < header.Count; ++col)
{
row.CreateCell(col).SetCellValue(header[col]);
}
}
//填充数据
foreach (var rowData in data)
{
rowID += 1;
IRow row = sheet.CreateRow(rowID);
for (Int32 col = 0; col < rowData.Count; ++col)
{
//row.CreateCell(col).SetCellValue(rowData[col]);
//row.CreateCell(col).SetCellType(CellType.Numeric);
//如果为数字,转换为double型
if (rowData[col] != null
&& Regex.IsMatch(rowData[col], @"^[+-]?/d*[.]?/d*$")
&& !Regex.IsMatch(rowData[col], @"^(((((1[6-9]|[2-9]\d)\d{2})-(0?[13578]|1[02])-(0?[1-9]|[12]\d|3[01]))|(((1[6-9]|[2-9]\d)\d{2})-(0?[13456789]|1[012])-(0?[1-9]|[12]\d|30))|(((1[6-9]|[2-9]\d)\d{2})-0?2-(0?[1-9]|1\d|2[0-8]))|(((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-0?2-29-)) (20|21|22|23|[0-1]?\d):[0-5]?\d:[0-5]?\d)$ ")
)
{
row.CreateCell(col).SetCellType(CellType.Numeric);
row.CreateCell(col).SetCellValue(double.Parse(rowData[col]));
}
else
{
row.CreateCell(col).SetCellValue(rowData[col]);
}
}
}
#region 设置作者
if (!string.IsNullOrEmpty(author))
{
rowID += 2;
IRow rowAuthor = sheet.CreateRow(rowID);
IRow rowDate = sheet.CreateRow(++rowID);
rowAuthor.CreateCell(data[0].Count - 2).SetCellValue("Author:");
rowAuthor.CreateCell(data[0].Count - 1).SetCellValue(author);
rowDate.CreateCell(data[0].Count - 2).SetCellValue("Date");
rowDate.CreateCell(data[0].Count - 1).SetCellValue(DateTime.Now.ToString("yyyy-MM-dd HH:mm"));
}
#endregion
return xlsx;
}
}
获取到xlsx工作簿后进行写入流的操作:
用以上方法生成的excel文件用WPS打开并没有任何异常,但是用Microsoft Office Excel打开时会报出请求修复的异常,原因是在使用MemoryStream的实例方法GetBuffer()会在原有的文件长度的基础上,增加一部分无效的字节数组,当使用office打开时无法识别后面的无效数组,就会去主动删除它,所以会报这个异常。
而解决方案就是将MemoryStream的实例方法GetBuffer()换成ToArray()方法,这个方法的作用是不管流中的数据是什么,都返回其真实长度,就可以避免office报修复的异常。