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


一、NPOI导出到Excel的代码

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;
      }
   }
}


按钮调用

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内容
在这里插入图片描述
然后再写入格式就会变成:数值直接被颜色覆盖了
在这里插入图片描述

那我先写背景色,在写数据会不会正常呢,依然有问题
在这里插入图片描述
再写数据就会变成:数值的默认背景色覆盖了原来设定的背景色
在这里插入图片描述

三、问题解决

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

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

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());
	}
}

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

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

最近更新

  1. TCP协议是安全的吗?

    2024-04-14 11:56:01       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-04-14 11:56:01       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-04-14 11:56:01       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-04-14 11:56:01       20 阅读

热门阅读

  1. JCYZ H3CNE-RS+

    2024-04-14 11:56:01       39 阅读
  2. opencv获取形态学卷积核

    2024-04-14 11:56:01       17 阅读
  3. 【电源专题】电量计RSOC精度评估方法

    2024-04-14 11:56:01       16 阅读
  4. 密码学:古老艺术与现代科学的交汇

    2024-04-14 11:56:01       15 阅读