.Net NPOI Excel 导出

NPOI 导出 Excel

最终效果图

 环境:Revit,WPF,NPOI 2.5.6,.Net Framework 4.7.2

一、引用 NPOI 

  右击项目引用,选择 "管理NuGet程序包",在浏览搜索 NPOI ,选择版本(我这里是2.5.6),安装

  

     

  

  安装成功后,引用里会出现这四个引用(NPOI,NPOI.OOXML,NPOI.OpenXml4Net,NPOI.OpenXmlFormats)

  在NuGet程序包里会多出来这两个(Portable.BouncyCastle,SharpZipLib)这是 NPOI 2.5.6 的依赖项;

  2.6.0的依赖的项会多,同时扩展了很多方法。我的需求只是导出Excel,所以这块我选择依赖项相对较少的 2.5.6 版本

二、实现导出Excle方法

  我这里粗略的封装了一个类,主要由以下几个方法组成

  创建表格()实现,创建列名,创建行

  设置单元格样式()在创建列名,创建行时会用到

  获取保存文件绝对路径()

  保存文件()

  我这里有两个导出方法,分别 “导出”,“自定义框架导出”。

  自定义框架导出,大概逻辑就是,在外层,创建好顶部和底部,再调用导出创建出红色区域

  导出的效果就是,没有前两行的标题和副标题,也没有最后一行的总计,就是红色区域

  

using Microsoft.Win32;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FormWork.Draft.ViewModels
{
    public class FileHelper
    {
        /// <summary>
        /// Excel行高,Height的单位是1/20个点。例:设置高度为25个点
        /// </summary>
        private static short rowHeight = 25 * 20;

        #region 导出Excel

        #region 导出

        /// <summary>
        /// 导出
        /// </summary>
        /// <param name="dt">数据源</param>
        /// <param name="strHeader">列名</param>
        /// <param name="fileName">绝对路径</param>
        /// <param name="sheetName">sheet页名</param>
        public static void Export(DataTable dt, string strHeader, string fileName, string sheetName = "Sheet1")
        {
            // 使用 NPOI 组件导出 Excel 文件

            //XSSFWorkbook:是操作Excel2007的版本,扩展名是.xlsx
            XSSFWorkbook workbook = new XSSFWorkbook();

            //HSSFWorkbook:是操作Excel2003以前(包括2003)的版本,扩展名是.xls
            //HSSFWorkbook workbook = new HSSFWorkbook();

            //创建Sheet
            ISheet sheet = workbook.CreateSheet(sheetName);

            //对列名拆分
            string[] strArry = strHeader.Split(',');

            //设置单元格样式
            ICellStyle style = SetCellStyle(workbook);

            //创建表格
            NPOICreateTable(dt, strArry, sheet, style, 0);

            // 将 Excel 文件保存到磁盘
            NPOISaveFile(workbook, fileName);

            // 释放资源
            //workbook.Dispose();
        }
        #endregion

        #region 自定义框架,导出

        /// <summary>
        /// 自定义顶部,导出
        /// </summary>
        /// <param name="dt">数据源</param>
        /// <param name="strArry">拆分后列名</param>
        /// <param name="fileName">绝对路径,路径+文件名+后缀</param>
        /// <param name="num">新一行索引,开始</param>
        /// <param name="workbook"></param>
        /// <param name="sheet"></param>
        public static void Export(DataTable dt, string[] strArry, string fileName, int num, XSSFWorkbook workbook, ISheet sheet)
        {
            //设置单元格样式
            ICellStyle style = SetCellStyle(workbook);

            //创建表格
            NPOICreateTable(dt, strArry, sheet, style, num);

            // 将 Excel 文件保存到磁盘
            NPOISaveFile(workbook, fileName);

            // 释放资源
            //workbook.Dispose();
        }
        #endregion

        #endregion

        #region 获取用户选择保存路径

        /// <summary>
        /// 获取让用户选择保存文件的绝对路径
        /// </summary>
        /// <returns></returns>
        public static string GetSaveFileRoute(string filter, string fileName)
        {
            SaveFileDialog dialog = new SaveFileDialog();
            dialog.Filter = filter;
            dialog.FileName = fileName;
            if (dialog.ShowDialog() == true)
            {
                return dialog.FileName;
            }
            return "";
        }

        #endregion

        #region 保存文件

        private static string NPOISaveFile(XSSFWorkbook workbook, string fileName)
        {
            try
            {
                // 将 Excel 文件保存到磁盘
                using (FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.Write))
                {
                    workbook.Write(fs);
                }

                return "";
            }
            catch (Exception err)
            {
                return err.Message;
            }
        }

        #endregion

        #region 创建表格

        /// <summary>
        /// 创建表格
        /// </summary>
        /// <param name="dt">数据源</param>
        /// <param name="strArry">拆分后的列名</param>
        /// <param name="sheet">Sheet页</param>
        /// <param name="style">样式</param>
        /// <param name="num">行索引</param>
        private static void NPOICreateTable(DataTable dt, string[] strArry, ISheet sheet, ICellStyle style, int num)
        {
            IRow row = null;//声明行

            #region 创建列名

            //在索引 num 的位置 创建一行
            row = sheet.CreateRow(num);
            row.Height = rowHeight;//设置行高

            //循环列名数组,创建单元格并赋值、样式
            for (int i = 0; i < strArry.Length; i++)
            {
                row.CreateCell(i).SetCellValue(strArry[i]);
                row.GetCell(i).CellStyle = style;
            }

            #endregion

            #region 创建行

            //循环数据源 创建行
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                //创建行
                row = sheet.CreateRow(num + 1);
                row.Height = rowHeight;//设置行高
                num++;//行索引自增

                //循环数据源列集合,创建单元格
                for (int j = 0; j < dt.Columns.Count; j++)
                {
                    string ValueType = "";//值类型
                    string Value = "";//值
                    //类型 和 值,赋值
                    if (dt.Rows[i][j].ToString() != null)
                    {
                        ValueType = dt.Rows[i][j].GetType().ToString();
                        Value = dt.Rows[i][j].ToString();
                    }
                    //根据不同数据类型,对数据处理。处理后创建单元格并赋值 和 样式
                    switch (ValueType)
                    {
                        case "System.String"://字符串类型
                            row.CreateCell(j).SetCellValue(Value);
                            break;
                        case "System.DateTime"://日期类型
                            System.DateTime dateV;
                            System.DateTime.TryParse(Value, out dateV);
                            row.CreateCell(j).SetCellValue(dateV.ToString("yyyy-MM-dd"));
                            break;
                        case "System.Boolean"://布尔型
                            bool boolV = false;
                            bool.TryParse(Value, out boolV);
                            row.CreateCell(j).SetCellValue(boolV);
                            break;
                        case "System.Int16"://整型
                        case "System.Int32":
                        case "System.Int64":
                        case "System.Byte":
                            int intV = 0;
                            int.TryParse(Value, out intV);
                            row.CreateCell(j).SetCellValue(intV);
                            break;
                        case "System.Decimal"://浮点型
                        case "System.Double":
                            double doubV = 0;
                            double.TryParse(Value, out doubV);
                            row.CreateCell(j).SetCellValue(doubV);
                            break;
                        case "System.DBNull"://空值处理
                            row.CreateCell(j).SetCellValue("");
                            break;
                        default:
                            row.CreateCell(j).SetCellValue("");
                            break;
                    }
                    row.GetCell(j).CellStyle = style;
                    //设置宽度
                    //sheet.SetColumnWidth(j, (Value.Length + 10) * 256);
                }
            }

            #endregion

            //循环列名数组,多所有列 设置 自动列宽
            for (int i = 0; i < strArry.Length; i++)
            {
                sheet.AutoSizeColumn(i);
            }
        }

        #endregion

        #region 设置单元格样式

        public static ICellStyle SetCellStyle(XSSFWorkbook workbook)
        {
            #region 单元格样式

            //创建一个样式
            ICellStyle style = workbook.CreateCellStyle();
            style.Alignment = HorizontalAlignment.Center;//水平对齐
            style.VerticalAlignment = VerticalAlignment.Center;//垂直对齐

            style.BorderBottom = BorderStyle.Thin;//下边框为细线边框
            style.BorderLeft = BorderStyle.Thin;//左边框
            style.BorderRight = BorderStyle.Thin;//上边框
            style.BorderTop = BorderStyle.Thin;//右边框

            #endregion

            return style;
        }

        #endregion
    }
}

三、调用导出

  OnExportCommand 此方法我是写在 ViewModel 里的。MVVM 模式,通过Command 绑定的事件。

  这个方法就相当于是 按钮的 Click事件

 View Code

 List转DataTable 扩展方法

四、Revit 启用 WPF窗体,WPF 导出

  在这里我遇到个问题,就是

  在Revit 命令类中,可以直接通过NPOI导出到excel,但命令打开WPF无法导出 会报错

  未能加载文件或程序集"NPOI,Version=2.5.6.0,Culture=neutral,PublicKeyToken=0df73ec7942b34e1"或它的某一个依赖项,系统找不到指定的文件

  我目前尚未了解其真正原因,只是通过不断测试,发现在 Execute 方法内 导出一次,便不会报错

  我现在的理解就是在Execute结束前不导出一次,便不会加载NPOI程序集。未知其原理与原因。

  如有遇到此问题的小伙伴,欢迎留言

        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            try
            {
                baseClass = new CmdBaseClass(commandData);

                VisualListView view = VisualListView.Load(this);

                //窗口一直显示在主程序之前
                System.Windows.Interop.WindowInteropHelper mainUI = new System.Windows.Interop.WindowInteropHelper(view);
                mainUI.Owner = System.Diagnostics.Process.GetCurrentProcess().MainWindowHandle;
                //打开非模态视图
                view.Show();

                #region NPOI/导出

                //未能加载文件或程序集"NPOI,Version=2.5.6.0,Culture=neutral,PublicKeyToken=0df73ec7942b34e1"或它的某一个依赖项,系统找不到指定的文件
                //此句勿删,在WPF中通过NPOI导出excel,如果不在此导出一次,就会报上面错误↑↑↑
                //在命令类中,可以直接通过NPOI导出到excel,但命令打开的WPF无法导出 会报错
                //目前尚未了解其真正原因,只是通过不断测试,发现在 Execute 方法内 导出一次,便不会报错
                //在Execute结束前不导出一次,便不会加载NPOI程序集
                Export();

                #endregion

                return Result.Succeeded;
            }
            catch (Exception err)
            {
                MessageBox.Show(err.Message, "错误");
                return Result.Failed;
            }
        }

        private void Export()
        {
            IWorkbook workbook = new XSSFWorkbook();
            ISheet worksheet = workbook.CreateSheet("Sheet1");

            // 将 Excel 文件保存到磁盘
            string fileName = @"D:\可视化清单" + DateTime.Now.ToString("yyyyMMddHHmmss") + ".xls";
            using (FileStream fs = new FileStream(fileName, FileMode.Create, FileAccess.Write))
            {
                workbook.Write(fs);
            }
            File.Delete(fileName);
        }

  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
### 回答1: .NET Core是一个跨平台的开源框架,可以用来开发各种类型的应用程序,包括Web应用、桌面应用和移动应用等。而NPOI是一个用于操作Excel、Word和PowerPoint等Microsoft Office文件的.NET库。 使用.NET Core的NPOI导出Excel模板可以实现将数据填充到Excel模板中的相应位置,并将其保存为最终的Excel文件。 首先,我们需要安装NPOI库。可以通过在.NET Core项目中的NuGet包管理器中搜索并安装NPOI库来实现。 然后,我们可以使用以下代码示例来实现数据填充到Excel模板中: ``` using NPOI.SS.UserModel; using NPOI.XSSF.UserModel; using System.IO; // 读取Excel模板 using (FileStream file = new FileStream("template.xlsx", FileMode.Open, FileAccess.Read)) { XSSFWorkbook workbook = new XSSFWorkbook(file); // 获取模板中的Sheet ISheet sheet = workbook.GetSheetAt(0); // 设置需要填充的数据 string data = "Hello, NPOI!"; // 将数据填充到指定位置(例如第一行第一列) IRow row = sheet.GetRow(0); ICell cell = row.GetCell(0); cell.SetCellValue(data); // 保存最终的Excel文件 using (FileStream outputFile = new FileStream("output.xlsx", FileMode.Create, FileAccess.Write)) { workbook.Write(outputFile); } } ``` 以上代码首先打开Excel模板文件,然后获取模板中的Sheet对象。接着,通过指定行和列获取要填充数据的单元格,并将数据填充到该单元格中。最后,将填充完成的Excel文件保存为最终的文件。 需要注意的是,以上示例代码中的模板文件为template.xlsx,保存的最终文件为output.xlsx,可以根据实际情况进行相应的修改。 以上就是使用.NET Core的NPOI库实现导出Excel模板的简单示例。希望对你有所帮助! ### 回答2: .NET Core是一个跨平台的开发框架,NPOI是一个.NET库,用于处理Microsoft Office文件,包括Excel。 在.NET Core中使用NPOI进行导出Excel模板的过程如下: 1. 首先,需要在.NET Core项目中引入NPOI库。可以通过NuGet包管理器或手动下载该库并引用到项目中。 2. 创建一个Excel模板文件,可以使用Microsoft Excel软件创建一个包含样式和格式的模板。该模板将用作导出数据的目标。 3. 在.NET Core项目中,使用NPOI库的API来加载Excel模板文件。可以使用`FileStream`类来打开Excel文件,然后使用`HSSFWorkbook`类来读取Excel工作簿。 4. 通过`HSSFWorkbook`类中的方法,获取Excel文件的工作表和单元格,可以基于需要进行修改或插入数据。 5. 将数据填充到模板中的相应位置。可以使用遍历的方式将数据按照模板中的格式填充到对应的单元格中。 6. 根据需求对数据进行处理,例如添加图表、应用公式、设置单元格样式等。 7. 保存修改后的Excel文件。使用`FileStream`类将修改后的工作簿保存到磁盘上的目标文件中。 总结,使用.NET Core中的NPOI导出Excel模板的过程包括:引入NPOI库、加载Excel模板文件、填充数据到模板中的单元格、处理数据、保存导出文件。这样可以方便地通过.NET Core应用程序生成包含特定格式和样式的Excel文件。 ### 回答3: 使用.NET Core的NPOI库可以很方便地将数据导出Excel模板。首先,我们需要安装NPOI库并在项目中引入相关命名空间。在导出数据之前,我们需要创建一个Excel模板,其中包含了我们要导出的数据的列名等信息。 首先,我们可以使用NPOI提供的Workbook类读取Excel模板文件,例如: ```csharp using NPOI.SS.UserModel; using NPOI.XSSF.UserModel; // 读取Excel模板文件 var templatePath = "template.xlsx"; var templateFileStream = new FileStream(templatePath, FileMode.Open, FileAccess.Read); var workbook = new XSSFWorkbook(templateFileStream); ``` 接下来,我们可以获取Excel模板中的工作表并创建一个Sheet对象,例如: ```csharp var sheet = workbook.GetSheetAt(0); ``` 然后,我们可以通过Sheet对象的CreateRow方法和CreateCell方法,来创建行和单元格,添加数据到Excel模板中,例如: ```csharp var rowIndex = 1; // 第二行开始写数据 // 假设要导出的数据是一个名为"students"的列表 foreach (var student in students) { var row = sheet.CreateRow(rowIndex); var cellIndex = 0; row.CreateCell(cellIndex++).SetCellValue(student.Name); row.CreateCell(cellIndex++).SetCellValue(student.Age); // 添加其他需要导出的列的数据 // ... rowIndex++; } ``` 最后,我们可以使用FileStream将导出Excel文件保存到磁盘上,例如: ```csharp var outputPath = "output.xlsx"; using (var outputFileStream = new FileStream(outputPath, FileMode.Create, FileAccess.Write)) { workbook.Write(outputFileStream); } ``` 以上就是使用.NET Core的NPOI导出数据至Excel模板的基本步骤。通过这种方式,我们可以将数据灵活地导出Excel,并可以根据需要进行格式设置、样式设置等操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值