【办公软件】使用NPOI库在C#中导出Excel文件写入单元格内容和格式时可能出现的相互覆盖问题

文章目录


一、NPOI导出到Excel的代码

csharp 复制代码
using System.IO;
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using System.Data;

namespace project
{   
   class ExcelWrite
   {
      private string _fileName;//文件路径
      public ExcelWrite(string fileName)
      {
         _fileName = fileName;
      }
      /// <summary>
      /// 写入方法
      /// </summary>
      /// <param name="dt">内存中数据</param>
      /// <returns></returns>
      public IWorkbook Write(DataTable dt)
      {
         IWorkbook workbook;
         if (File.Exists(_fileName))
         {
            string extension = Path.GetExtension(_fileName).ToLower();//获取文件扩展名
            using (FileStream readStream = File.OpenRead(_fileName))
            {
               workbook = null;
               if (extension == ".xls")
               {
                  workbook = new HSSFWorkbook(readStream);
               }
               else
               {
                  workbook = new XSSFWorkbook(readStream);
               }
            }
            ISheet sheet = workbook.GetSheetAt(0);//根据索引或名称获取工作表对象
            int num = sheet.LastRowNum + 1;//获取工作表做最大行数
            for (int i = 0; i < dt.Rows.Count; i++)
            {
               IRow row = sheet.CreateRow(num+i);
               for (int j = 0; j < dt.Columns.Count; j++)
               {
                  ICell cell = row.CreateCell(j);
                  string value = dt.Rows[i][j].ToString();
                  cell.SetCellValue(value);
               }
            }
         }
         else
         {
            string extension = Path.GetExtension(_fileName).ToLower();
            if (extension.Equals(".xls"))
            {
                workbook = new HSSFWorkbook();
            }
            else
            {
                workbook = new XSSFWorkbook();
            }      
			ICellStyle cellStyle = workbook.CreateCellStyle();
            cellStyle .FillForegroundColor = NPOI.HSSF.Util.HSSFColor.Red.Index;
            cellStyle .FillPattern = FillPattern.SolidForeground;
            cellStyle .FillBackgroundColor = NPOI.HSSF.Util.HSSFColor.Red.Index;
     
            ISheet sheet = workbook.CreateSheet("Sheet0");//根据索引或名称创建工作表对象
            for (int i = 0; i < dt.Rows.Count; i++)
            {
               IRow row = sheet.CreateRow(i);
               for (int j = 0; j < dt.Columns.Count; j++)
               {
                    ICell cell = row.CreateCell(j);
                    string value = dt.Rows[i][j].ToString();
                    cell.CellStyle=cellStyle;  // A这里给定样式
                    cell.SetCellValue(value);  // B这里给定数值
                }
            }
         }
         using (FileStream stream = File.Create(_fileName, 1000))
         {
             workbook.Write(stream);
             workbook.Close();
         }
         return workbook;
      }
   }
}

按钮调用

csharp 复制代码
private void Button1_Click(object sender, EventArgs e)
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("姓名");
            dt.Columns.Add("性别");
            dt.Columns.Add("年龄");
            var row = dt.NewRow();
            row["姓名"] = "小明";
            row["性别"] = "男";
            row["年龄"] = 26;
            dt.Rows.Add(row);
            string FileName = "E://VS项目//test1.xlsx";
            ExcelWrite writerData = new ExcelWrite(FileName);
            writerData.Write(dt);
        }

二、单元格内容和单元格数值相互覆盖问题

就是不论是先写格式,还是先写数值,后者都会将前者内容覆盖。

例如:我先写入1111内容

然后再写入格式就会变成:数值直接被颜色覆盖了

那我先写背景色,在写数据会不会正常呢,依然有问题

再写数据就会变成:数值的默认背景色覆盖了原来设定的背景色

三、问题解决

重写设定数值和格式的函数,将二者同时设置。

我们新增这样一个自定义函数:

csharp 复制代码
public static void SetCellValue(ICell cell, object obj)
{
	if (obj.GetType() == typeof(int))
	{
		cell.SetCellValue((int)obj);
	}
	else if (obj.GetType() == typeof(double))
	{
		cell.SetCellValue((double)obj);
	}
	else if (obj.GetType() == typeof(IRichTextString))
	{
		cell.SetCellValue((IRichTextString)obj);
	}
	else if (obj.GetType() == typeof(string))
	{
		cell.SetCellValue(obj.ToString());
	}
	else if (obj.GetType() == typeof(DateTime))
	{
	 	cell.SetCellValue((DateTime)obj);
	}
	else if (obj.GetType() == typeof(bool))
	{
		cell.SetCellValue((bool)obj);
	}
	else 
	{
		cell.SetCellValue(obj.ToString());
	}
}

接下来在上面导出的那个函数中这样调用这个自定义的同时设置值和格式的函数:

csharp 复制代码
using System.IO;
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using System.Data;

namespace project
{   
   class ExcelWrite
   {
      private string _fileName;//文件路径
      public ExcelWrite(string fileName)
      {
         _fileName = fileName;
      }
      /// <summary>
      /// 写入方法
      /// </summary>
      /// <param name="dt">内存中数据</param>
      /// <returns></returns>
      public IWorkbook Write(DataTable dt)
      {
         IWorkbook workbook;
         if (File.Exists(_fileName))
         {
            string extension = Path.GetExtension(_fileName).ToLower();//获取文件扩展名
            using (FileStream readStream = File.OpenRead(_fileName))
            {
               workbook = null;
               if (extension == ".xls")
               {
                  workbook = new HSSFWorkbook(readStream);
               }
               else
               {
                  workbook = new XSSFWorkbook(readStream);
               }
            }
            ISheet sheet = workbook.GetSheetAt(0);//根据索引或名称获取工作表对象
            int num = sheet.LastRowNum + 1;//获取工作表做最大行数
            for (int i = 0; i < dt.Rows.Count; i++)
            {
               IRow row = sheet.CreateRow(num+i);
               for (int j = 0; j < dt.Columns.Count; j++)
               {
                  ICell cell = row.CreateCell(j);
                  string value = dt.Rows[i][j].ToString();
                  cell.SetCellValue(value);
               }
            }
         }
         else
         {
            string extension = Path.GetExtension(_fileName).ToLower();
            if (extension.Equals(".xls"))
            {
                workbook = new HSSFWorkbook();
            }
            else
            {
                workbook = new XSSFWorkbook();
            }      
			ICellStyle cellStyle = workbook.CreateCellStyle();
            cellStyle .FillForegroundColor = NPOI.HSSF.Util.HSSFColor.Red.Index;
            cellStyle .FillPattern = FillPattern.SolidForeground;
            cellStyle .FillBackgroundColor = NPOI.HSSF.Util.HSSFColor.Red.Index;
     
            ISheet sheet = workbook.CreateSheet("Sheet0");//根据索引或名称创建工作表对象
            for (int i = 0; i < dt.Rows.Count; i++)
            {
               IRow row = sheet.CreateRow(i);
               for (int j = 0; j < dt.Columns.Count; j++)
               {
                    ICell cell = row.CreateCell(j);
                    string value = dt.Rows[i][j].ToString();
                    cell.CellStyle=cellStyle;  // A这里给定样式
                    SetCellValue(cell, value);  // B这里给定数值   !!!!!注意这里不使用默认的设置函数,而是自定义的
                }
            }
         }
         using (FileStream stream = File.Create(_fileName, 1000))
         {
             workbook.Write(stream);
             workbook.Close();
         }
         return workbook;
      }
   }
}

注意框出来的代码,就是这句调用不一样,可以同时设置值和格式。

最后这个问题就完美解决!

四、总结

这篇文章介绍了使用NPOI库在C#中导出Excel文件的代码,并解决了在写入单元格内容和格式时可能出现的相互覆盖问题。主要内容包括:

  1. 使用NPOI库来操作Excel文件,包括读取和写入数据。
  2. 创建一个自定义的 SetCellValue 函数,用于同时设置单元格的值和样式,避免内容和格式相互覆盖的问题。
  3. 通过示例代码演示了如何在导出Excel文件时正确应用单元格的内容和格式,确保导出的Excel文件格式正确。

总的来说,这篇文章通过实际代码示例详细说明了如何使用NPOI库导出Excel文件,并解决了可能出现的单元格内容和格式相互覆盖的问题,为C#开发者提供了一个实用的参考。希望这篇总结对您有帮助!

相关推荐
代码笔耕几秒前
面向对象开发实践之消息中心设计(二)
java·后端·架构
Lv117700810 分钟前
Visual Studio中Array数组的常用查询方法
笔记·算法·c#·visual studio
要开心吖ZSH16 分钟前
应用集成平台-系统之间的桥梁-思路分享
java·kafka·交互
TsengOnce19 分钟前
阿里云ECS多版本JDK切换
java·python·阿里云
wearegogog12322 分钟前
基于C#的FTP客户端实现方案
java·网络·c#
听风吟丶23 分钟前
Java NIO 深度解析:从核心组件到高并发实战
java·开发语言·jvm
野生技术架构师30 分钟前
Java面试题及答案总结(互联网大厂新版)
java·面试·状态模式
a努力。31 分钟前
小红书Java面试被问:ThreadLocal 内存泄漏问题及解决方案
java·jvm·后端·算法·面试·架构
此生只爱蛋31 分钟前
【Redis】String 字符串
java·数据库·redis
C++业余爱好者32 分钟前
Java开发中Entity、VO、DTO、Form对象详解
java·开发语言