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

相关推荐
哦虎!6 小时前
【JavaEE】网络初识
java
for_ever_love__6 小时前
MySQL ORDER BY 排序优化:从 Using filesort 到索引有序扫描(含双路 / 单路排序原理)
java·mysql·优化·存储·by·order·filesort
我是人✓7 小时前
Java文件上传三方式对比:从传统到SpringBoot
java·开发语言
欣栀♡7 小时前
JVM 频繁 Full GC 先看日志括号里的 cause,jstat 的 FGC 在 JDK 8 上会骗人
java·jvm
IT研究室8 小时前
最新计算机毕业设计选题推荐-基于spring boot的葡萄酒文化宣传网站-网站-文档指导-Java-springboot
java·spring boot·课程设计
慧都小项8 小时前
MyEclipse 中创建和测试 JAX-RS REST 接口:从项目配置到 REST Explorer
java·restful·myeclipse·jax-rs
Wang's Blog8 小时前
Java 项目实战: 交友项目 - 入门案例:编写 Dubbo 服务提供者
java·dubbo·交友
秋饼8 小时前
Spring AI 2.0 结构化输出企业级实战:从 BeanOutputConverter 源码到生产级解析容错
java·ai·技术分享·后端开发
摇滚侠8 小时前
《计算机是如何工作的:人人都能懂的计算机软硬件工作原理》第 9 章 机器码与汇编语言 阅读笔记 9
java·开发语言·笔记
Cc.Y8 小时前
Java零基础入门:深入Java核心:文件IO与序列化全解
java·开发语言·python