首页 » 网络编程 » Asp.net

.NET6导入和导出EXCEL

Asp.net 2021-12-24

使用NPOI导入.xlsx遇到“EOF in header”报错,网上找好很多方法,没解决,最后换成EPPlus.Core导入。

导出默认是.xls。

NPOI操作类:

using NPOI.HPSF;
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using System.Collections;
using System.Data;

namespace CommonUtils
{
    /// <summary>
    /// Excel操作相关
    /// </summary>
    public class ExcelHelper
    {
        #region 读取Excel到DataTable

        /// <summary>
        /// 读取Excel文件的内容
        /// </summary>
        /// <param name="path"></param>
        /// <param name="sheetName">工作表名称</param>
        /// <returns></returns>
        public static DataTable GetDataTable(string path, string sheetName = null)
        {
            if (path.ToLower().EndsWith(".xlsx"))
                return EPPlusHelper.WorksheetToTable(path, sheetName);

            using (FileStream file = new FileStream(path, FileMode.Open, FileAccess.Read))
            {
                return GetDataTable(file, sheetName);
            }
        }

        /// <summary>
        /// 从Excel文件流读取内容
        /// </summary>
        /// <param name="file"></param>
        /// <param name="sheetName"></param>
        /// <returns></returns>
        public static DataTable GetDataTable(Stream file, string contentType, string sheetName = null)
        {
            //载入工作簿
            IWorkbook workBook = null;
            if (contentType == "application/vnd.ms-excel")
            {
                workBook = new HSSFWorkbook(file);
            }
            else if (contentType == "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
            {
                workBook = new XSSFWorkbook(file);
            }
            else
            { try {
                    workBook = new HSSFWorkbook(file);
                }
                catch
                {
                    try
                    {
                        workBook = new XSSFWorkbook(file);
                    }
                    catch
                    {
                        throw new Exception("文件格式不被支持!");
                    }
                }
            }

            //获取工作表(sheetName为空则默认获取第一个工作表)
            var sheet = string.IsNullOrEmpty(sheetName) ? workBook.GetSheetAt(0) : workBook.GetSheet(sheetName);
            //生成DataTable
            if (sheet != null)
                return GetDataTable(sheet);
            else
                throw new Exception(string.Format("工作表{0}不存在!", sheetName ?? ""));

        }

        /// <summary>
        /// 读取工作表数据
        /// </summary>
        /// <param name="sheet"></param>
        /// <returns></returns>
        private static DataTable GetDataTable(ISheet sheet)
        {
            IEnumerator rows = sheet.GetRowEnumerator();

            DataTable dt = new DataTable(sheet.SheetName);

            //默认第一个非空行为列头
            bool isTitle = true;
            //标题行索引
            int titleRowIndex = 0;
            //默认列头后的第一个数据行,作为DataTable列类型的依据
            IRow firstDataRow = null;

            while (rows.MoveNext())
            {
                IRow row = null;
                if (rows.Current is XSSFRow)//*.xlsx
                {
                    row = (XSSFRow)rows.Current;
                }
                else//*.xls
                {
                    row = (HSSFRow)rows.Current;
                }

                //是否空行
                if (IsEmptyRow(row))
                {
                    if (isTitle)
                    {
                        titleRowIndex++;
                    }
                    continue;
                }
                else
                {
                    if (isTitle)
                    {
                        firstDataRow = sheet.GetRow(titleRowIndex + 1);//默认列头后的第一个数据行,作为DataTable列类型的依据
                    }
                }

                DataRow dr = dt.NewRow();

                for (int i = 0; i < row.LastCellNum; i++)
                {
                    var cell = row.GetCell(i);

                    if (isTitle)
                    {
                        var firstDataRowCell = firstDataRow.GetCell(i);
                        if (firstDataRowCell != null || cell != null)
                        {
                            dt.Columns.Add(cell.StringCellValue.Trim());
                        }
                        else
                        {
                            dt.Columns.Add(string.Format("未知列{0}", i + 1));
                        }
                    }
                    else
                    {
                        if (i > dt.Columns.Count - 1) break;
                        dr[i] = GetCellValue(cell, dt.Columns[i].DataType);
                    }

                }
                if (!isTitle && !IsEmptyRow(dr, dt.Columns.Count))
                {
                    dt.Rows.Add(dr);
                }
                isTitle = false;
            }

            return dt;
        }

        /// <summary>
        /// 获取单元格值
        /// </summary>
        /// <param name="cell"></param>
        /// <param name="colType"></param>
        /// <returns></returns>
        private static object GetCellValue(ICell cell, Type colType)
        {
            if (cell == null || cell.ToString().ToUpper().Equals("NULL") || cell.CellType == NPOI.SS.UserModel.CellType.Blank)
                return DBNull.Value;

            object val = null;
            switch (cell.CellType)
            {
                case NPOI.SS.UserModel.CellType.Boolean:
                    val = cell.BooleanCellValue;
                    break;
                case NPOI.SS.UserModel.CellType.Numeric:
                    var cellValueStr = cell.ToString().Trim();
                    if (cellValueStr.IndexOf('-') >= 0 || cellValueStr.IndexOf('/') >= 0)
                    {
                        DateTime d = DateTime.MinValue;
                        DateTime.TryParse(cellValueStr, out d);
                        if (!d.Equals(DateTime.MinValue)) val = cellValueStr;
                    }
                    if (val == null)
                    {
                        decimal vNum = 0;
                        decimal.TryParse(cellValueStr, out vNum);
                        val = vNum;
                    }
                    break;
                case NPOI.SS.UserModel.CellType.String:
                    val = cell.StringCellValue;
                    break;
                case NPOI.SS.UserModel.CellType.Error:
                    val = cell.ErrorCellValue;
                    break;
                case NPOI.SS.UserModel.CellType.Formula:
                default:
                    val = "=" + cell.CellFormula;
                    break;
            }

            return val;
        }

        /// <summary>
        /// 检查是否空数据行
        /// </summary>
        /// <param name="dr"></param>
        /// <returns></returns>
        private static bool IsEmptyRow(DataRow dr, int colCount)
        {
            bool isEmptyRow = true;
            for (int i = 0; i < colCount; i++)
            {
                if (dr[i] != null && !dr[i].Equals(DBNull.Value))
                {
                    isEmptyRow = false;
                    break;
                }
            }
            return isEmptyRow;
        }

        /// <summary>
        /// 检查是否空的Excel行
        /// </summary>
        /// <param name="row"></param>
        /// <returns></returns>
        private static bool IsEmptyRow(IRow row)
        {
            bool isEmptyRow = true;
            for (int i = 0; i < row.LastCellNum; i++)
            {
                if (row.GetCell(i) != null)
                {
                    isEmptyRow = false;
                    break;
                }
            }

            return isEmptyRow;
        }
        #endregion

        #region 生成DataTable到Excel

        /// <summary>
        /// 生成Excel数据到路径
        /// </summary>
        /// <param name="data"></param>
        /// <param name="path"></param>
        public static void GenerateExcel(DataTable data, string path)
        {
            var workBook = GenerateExcelData(data);
            //保存至路径
            using (FileStream fs = File.OpenWrite(path)) //打开一个xls文件,如果没有则自行创建,如果存在则在创建时不要打开该文件!
            {
                workBook.Write(fs);   //向打开的这个xls文件中写入mySheet表并保存。
            }
        }

        /// <summary>
        /// 生成Excel数据到字节流
        /// </summary>
        /// <param name="data"></param>
        /// <param name="path"></param>
        public static byte[] GenerateExcel(DataTable data)
        {
            var workBook = GenerateExcelData(data);
            using (MemoryStream ms = new MemoryStream())
            {
                workBook.Write(ms);
                return ms.GetBuffer();
            }
        }

        /// <summary>
        /// 生成DataTable到Excel
        /// </summary>
        /// <param name="data"></param>
        /// <param name="path"></param>
        private static IWorkbook GenerateExcelData(DataTable data)
        {
            //创建工作簿
            var workBook = new HSSFWorkbook();
            //生成文件基本信息
            GenerateSummaryInformation(workBook);
            //创建工作表
            var sheet = workBook.CreateSheet("Sheet1");
            //创建标题行
            if (data != null && data.Columns.Count > 0)
            {
                IRow row = sheet.CreateRow(0);
                for (int i = 0; i < data.Columns.Count; i++)
                {
                    var cell = row.CreateCell(i);
                    cell.SetCellValue(data.Columns[i].ColumnName);
                }
            }
            //创建数据行
            if (data != null && data.Rows.Count > 0)
            {
                for (int rowIndex = 1; rowIndex <= data.Rows.Count; rowIndex++)
                {
                    IRow row = sheet.CreateRow(rowIndex);
                    for (int colIndex = 0; colIndex < data.Columns.Count; colIndex++)
                    {
                        var cell = row.CreateCell(colIndex);
                        var cellValue = data.Rows[rowIndex - 1][colIndex];
                        switch (data.Columns[colIndex].DataType.Name)
                        {
                            case "Byte":
                            case "Int16":
                            case "Int32":
                            case "Int64":
                            case "Decimal":
                            case "Single":
                            case "Double":
                                double doubleVal = 0;
                                if (cellValue != null && !cellValue.Equals(System.DBNull.Value))
                                {
                                    double.TryParse(cellValue.ToString(), out doubleVal);
                                    cell.SetCellValue(doubleVal);
                                }
                                break;
                            case "DateTime":
                                DateTime dtVal = DateTime.MinValue;
                                if (cellValue != null && !cellValue.Equals(System.DBNull.Value))
                                {
                                    DateTime.TryParse(cellValue.ToString(), out dtVal);
                                    if (dtVal != DateTime.MinValue)
                                    {
                                        cell.SetCellValue(dtVal);
                                    }
                                }
                                break;
                            default:
                                if (cellValue != null && !cellValue.Equals(System.DBNull.Value))
                                {
                                    cell.SetCellValue(cellValue.ToString());
                                }
                                break;
                        }

                    }
                }
            }

            return workBook;
        }

        /// <summary>
        /// 创建文档的基本信息(右击文件属性可看到的)
        /// </summary>
        /// <param name="workBook"></param>
        private static void GenerateSummaryInformation(HSSFWorkbook workBook)
        {
            DocumentSummaryInformation dsi = PropertySetFactory.CreateDocumentSummaryInformation();
            dsi.Company = "Company";

            SummaryInformation si = PropertySetFactory.CreateSummaryInformation();
            si.Subject = "Subject";//主题
            si.Author = "Author";//作者

            workBook.DocumentSummaryInformation = dsi;
            workBook.SummaryInformation = si;
        }

        #endregion
    }
}

EPPlus.Core工具类:

//using EPPlus.Extensions;
using OfficeOpenXml;
using System.Data;


namespace CommonUtils
{
    /// <summary>
    /// 使用  EPPlus 第三方的组件读取Excel
    /// </summary>
    public class EPPlusHelper
    {
        private static string GetString(object obj)
        {

            if (obj == null)
                return "";

            return obj.ToString();

        }

        /// <summary>
        ///将指定的Excel的文件转换成DataTable (Excel的第一个sheet)
        /// </summary>
        /// <param name="fullFielPath">文件的绝对路径</param>
        /// <returns></returns>
        public static DataTable WorksheetToTable(string fullFielPath, string sheetName = null)
        {
            //如果是“EPPlus”,需要指定LicenseContext。
            //EPPlus.Core 不需要指定。
            //ExcelPackage.LicenseContext = LicenseContext.NonCommercial;

            FileInfo existingFile = new FileInfo(fullFielPath);

            ExcelPackage package = new ExcelPackage(existingFile);
            ExcelWorksheet worksheet = null;

            if (string.IsNullOrEmpty(sheetName))
            {
                //不传入 sheetName 默认取第1个sheet。
                //EPPlus 索引是0
                //EPPlus.Core 索引是1
                worksheet = package.Workbook.Worksheets[1];
            }
            else
            {                
                worksheet = package.Workbook.Worksheets[sheetName];
            }
             
            if (worksheet == null)
                throw new Exception("指定的sheetName不存在");

            return WorksheetToTable(worksheet);
        }

        /// <summary>
        /// 将worksheet转成datatable
        /// </summary>
        /// <param name="worksheet">待处理的worksheet</param>
        /// <returns>返回处理后的datatable</returns>
        public static DataTable WorksheetToTable(ExcelWorksheet worksheet)
        {
            //获取worksheet的行数
            int rows = worksheet.Dimension.End.Row;
            //获取worksheet的列数
            int cols = worksheet.Dimension.End.Column;

            DataTable dt = new DataTable(worksheet.Name);
            DataRow dr = null;
            for (int i = 1; i <= rows; i++)
            {
                if (i > 1)
                    dr = dt.Rows.Add();

                for (int j = 1; j <= cols; j++)
                {
                    //默认将第一行设置为datatable的标题
                    if (i == 1)
                        dt.Columns.Add(GetString(worksheet.Cells[i, j].Value));
                    //剩下的写入datatable
                    else
                        dr[j - 1] = GetString(worksheet.Cells[i, j].Value);
                }
            }
            return dt;
        }
    }
}

使用:

// See https://aka.ms/new-console-template for more information
using CommonUtils;
using System.Data;

Console.WriteLine("Hello, World!");


try
{
    string dir = AppContext.BaseDirectory;
    //2003
    string fullName = Path.Combine(dir, "测试excel.xls");
    DataTable dt = ExcelHelper.GetDataTable(fullName);

    Console.WriteLine("Hello, World!" + dir);
    //2007
    string fullName2 = Path.Combine(dir, "测试excel.xlsx");
    //dt = ExcelHelper.GetDataTable(fullName);
    //DataTable dt2 = ExcelHelper.GetDataTable(fullName2, "sheetf");
    DataTable dt2 = ExcelHelper.GetDataTable(fullName2);

    string saveFullName = Path.Combine(dir, "save_excel.xls");
    //ExcelHelper2.ExportExcelByMemoryStream(saveFullName, dt2);
    string saveFullName2 = Path.Combine(dir, "save_excel2.xls");
    ExcelHelper.GenerateExcel(dt2, saveFullName2);

    Console.WriteLine("Hello, World!" + dir);
}
catch (Exception ex)
{
    Console.WriteLine("ex:" + ex.Message);
}


Console.ReadKey();

.NET6导入和导出EXCEL

源码:http://xiazai.jb51.net/202112/yuanma/ConsoleOperExcel_jb51.rar,使用vs2022 。

到此这篇关于.NET6导入和导出EXCEL的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持www.580doc.com。


上一篇:.net 6项目实现压缩发布下一篇:.Net?6中WebApplicationBuilder介绍和用法
程序园_程序员的世界 Copyright © 2020- www.580doc.com. Some Rights Reserved.