【办公软件】使用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#开发者提供了一个实用的参考。希望这篇总结对您有帮助!

相关推荐
全栈老实人_2 分钟前
农家乐系统|Java|SSM|VUE| 前后端分离
java·开发语言·tomcat·maven
customer084 分钟前
【开源免费】基于SpringBoot+Vue.JS安康旅游网站(JAVA毕业设计)
java·vue.js·spring boot·后端·kafka·开源·旅游
点点滴滴的记录21 分钟前
Java的CompletableFuture实现原理
java·开发语言·javascript
xiaolingting22 分钟前
Java 引用是4个字节还是8个字节?
java·jvm·引用·指针压缩
一只傻小白,27 分钟前
JAVA项目中freemarker静态模板技术
java·开发语言
袁庭新27 分钟前
Spring Boot项目接收前端参数的11种方式
java·springboot·袁庭新·如何接收前端数据·boot接收数据
机跃29 分钟前
递归算法常见问题(Java)
java·开发语言·算法
程序员-小李1 小时前
餐厅下单助手系统(Java+MySQL)
java·开发语言·mysql
开心工作室_kaic1 小时前
springboot496基于java手机销售网站设计和实现(论文+源码)_kaic
java·开发语言·智能手机
像少年啦飞驰点、1 小时前
SpringBoot + HttpSession 自定义生成sessionId
java·开发语言