针对C#中MemoryStream写入excel 文件的一些异常给出的一些解决方案

时间:2024-03-23 21:22:03

关于"发现*.xlsx中部分内容有问题,是否让我们尽量尝试恢复?如果您信任此工作簿的源,请单击"是""的解决方案。

针对C#中MemoryStream写入excel 文件的一些异常给出的一些解决方案
关于这个问题,我给出的解决方案是针对使用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工作簿后进行写入流的操作:
针对C#中MemoryStream写入excel 文件的一些异常给出的一些解决方案
用以上方法生成的excel文件用WPS打开并没有任何异常,但是用Microsoft Office Excel打开时会报出请求修复的异常,原因是在使用MemoryStream的实例方法GetBuffer()会在原有的文件长度的基础上,增加一部分无效的字节数组,当使用office打开时无法识别后面的无效数组,就会去主动删除它,所以会报这个异常。
而解决方案就是将MemoryStream的实例方法GetBuffer()换成ToArray()方法,这个方法的作用是不管流中的数据是什么,都返回其真实长度,就可以避免office报修复的异常。
针对C#中MemoryStream写入excel 文件的一些异常给出的一些解决方案
针对C#中MemoryStream写入excel 文件的一些异常给出的一些解决方案