当前位置: 首页 > article >正文

WPF编程excel表格操作

WPF编程excel表格操作

  • 摘要
  • NPOI安装
  • 封装代码
  • 测试代码

摘要

Excel操作几种方式

  • 使用开源库NPOI(常用,操作丰富)
  • 使用Microsoft.Office.Interop.Excel COM组件(兼容性问题)
  • 使用OpenXml(效率高)
  • 使用OleDb(过时)

NPOI安装

在这里插入图片描述

封装代码

using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data;

using NPOI.SS.Util;
using NPOI.SS.UserModel;    
using NPOI.XSSF.UserModel;  // 对于.xlsx文件
using NPOI.HSSF.UserModel;  // 对于.xls文件

namespace GasAlarmTestTool
{
    internal class ExcelTools
    {
        /// <summary>
        /// 创建Excel表
        /// </summary>
        /// <param name="filePath"></param>
        /// <param name="dataTable"></param>
        public void CreateNewExcel(string filePath, DataTable dataTable)
        {
            IWorkbook workbook;
            if (filePath.EndsWith(".xlsx"))
            {
                workbook = new XSSFWorkbook(); // 创建 .xlsx 文件
            }
            else
            {
                workbook = new HSSFWorkbook(); // 创建 .xls 文件
            }

            var sheet = workbook.CreateSheet("Sheet1");


            // 写入表头
            var headerRow = sheet.CreateRow(0);
            for (int i = 0; i < dataTable.Columns.Count; i++)
            {
                headerRow.CreateCell(i).SetCellValue(dataTable.Columns[i].ColumnName);
            }

            // 写入数据
            for (int i = 0; i < dataTable.Rows.Count; i++)
            {
                var dataRow = sheet.CreateRow(i + 1);
                for (int j = 0; j < dataTable.Columns.Count; j++)
                {
                    dataRow.CreateCell(j).SetCellValue(dataTable.Rows[i][j].ToString());
                }
            }

            SetUniformColumnWidth(sheet, 20);   // 默认统一列宽20

            // 保存文件
            using (var stream = new FileStream(filePath, FileMode.Create, FileAccess.Write))
            {
                workbook.Write(stream);
            }

        }

        /// <summary>
        /// 追加Excel表
        /// 追加数据时,可以定位到现有数据的末尾,创建新行并写入。
        /// </summary>
        /// <param name="filePath"></param>
        /// <param name="dataTable"></param>
        public void AppendDataToExistingExcel(string filePath, DataTable dataTable)
        {
            IWorkbook workbook;
            using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
            {
                workbook = filePath.EndsWith(".xlsx") ? (IWorkbook)new XSSFWorkbook(stream) : new HSSFWorkbook(stream);
            }

            var sheet = workbook.GetSheetAt(0);
            int lastRowNum = sheet.LastRowNum;

            for (int i = 0; i < dataTable.Rows.Count; i++)
            {
                var dataRow = sheet.CreateRow(lastRowNum + i + 1);
                for (int j = 0; j < dataTable.Columns.Count; j++)
                {
                    dataRow.CreateCell(j).SetCellValue(dataTable.Rows[i][j].ToString());
                }
            }

            using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Write))
            {
                workbook.Write(stream);
            }
        }

        /// <summary>
        /// 查找指定列是否存在item项
        /// </summary>
        /// <param name="filePath"></param>
        /// <param name="item"></param>
        /// <param name="colIndex"></param>
        /// <returns></returns>
        public bool SearchColumnExitsItem(string filePath, string item, int colIndex)
        {
            IWorkbook workbook;
            using (var stream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
            {
                workbook = filePath.EndsWith(".xlsx") ? (IWorkbook)new XSSFWorkbook(stream) : new HSSFWorkbook(stream);
            }

            var sheet = workbook.GetSheetAt(0);

            // 遍历每一行
            for (int row = 0; row <= sheet.LastRowNum; row++)
            {
                IRow currentRow = sheet.GetRow(row);
                if (currentRow != null)
                {
                    // 遍历每一列
                    for (int column = 0; column < currentRow.LastCellNum; column++)
                    { 
                        ICell currentCell = currentRow.GetCell(column);
                        var cellValue = currentCell.ToString();

                        if ((column == colIndex) && (cellValue == item))
                        {
                            return true;
                        }
                    }
                }
            }     

            return false;
        }

        /// <summary>
        /// 设置列宽
        /// </summary>
        /// <param name="workbook"></param>
        /// <param name="sheetIndex"></param>
        /// <param name="columnIndex"></param>
        public void SetColumnWidth(IWorkbook workbook, int sheetIndex, int columnIndex)
        {
            var sheet = workbook.GetSheetAt(sheetIndex);

            // 设置列宽(单位是 1/256 字符宽度)
            sheet.SetColumnWidth(columnIndex, 20 * 256); // 设置第1列宽度为20
        }

        /// <summary>
        /// 设置行高
        /// </summary>
        /// <param name="workbook"></param>
        /// <param name="sheetIndex"></param>
        /// <param name="rowIndex"></param>
        public void SetColumnRowHeight(IWorkbook workbook, int sheetIndex, int rowIndex)
        {
            var sheet = workbook.GetSheetAt(sheetIndex);

            // 设置行高(单位是点数)
            var row = sheet.GetRow(rowIndex) ?? sheet.CreateRow(rowIndex);
            row.HeightInPoints = 25; // 设置行高为25点
        }

        /// <summary>
        /// 同时设置列宽和行高
        /// </summary>
        /// <param name="workbook"></param>
        /// <param name="sheetIndex"></param>
        /// <param name="columnIndex"></param>
        /// <param name="rowIndex"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        public void SetColumnWidthAndRowHeight(IWorkbook workbook, int sheetIndex, int columnIndex, int rowIndex, int width, int height)
        {
            var sheet = workbook.GetSheetAt(sheetIndex);

            // 设置列宽(单位是1/256字符宽度)
            sheet.SetColumnWidth(columnIndex, width * 256); // 设置第1列宽度为 20 

            var row = sheet.GetRow(rowIndex) ?? sheet.CreateRow(rowIndex); 
            row.HeightInPoints = height; // 25
        }


        /// <summary>
        /// 设置统一行高
        /// </summary>
        /// <param name="sheet"></param>
        /// <param name="heightInPoints"></param>
        public void SetUniformRowHeight(ISheet sheet, float heightInPoints)
        {
            for (int i = 0; i < sheet.LastRowNum; i++)
            { 
                var row = sheet.GetRow(i) ?? sheet.CreateRow(i);
                row.HeightInPoints = heightInPoints;
            }
        }

        /// <summary>
        /// 设置统一列宽
        /// </summary>
        /// <param name="sheet"></param>
        /// <param name="widthInCharacters"></param>
        public void SetUniformColumnWidth(ISheet sheet, int widthInCharacters)
        {
            for (int i = 0; i < sheet.GetRow(0).LastCellNum; i++) // 以第一行的单元格数量为列数
            {
                sheet.SetColumnWidth(i, widthInCharacters * 256); // 设置列宽
            }
        }

        /// <summary>
        /// 设置统一行高和列宽
        /// </summary>
        /// <param name="sheet"></param>
        /// <param name="rowHeightInPoints"></param>
        /// <param name="columnWidthCharacters"></param>
        public void SetUniformRowHeightAndColumnWidth(ISheet sheet, float rowHeightInPoints, int columnWidthCharacters)
        {
            SetUniformRowHeight(sheet, rowHeightInPoints);

            SetUniformColumnWidth(sheet, columnWidthCharacters);
        }


        /// <summary>
        /// 合并单元格可以通过 CellRangeAddress 设置,需要定义起始和结束的行列。
        /// </summary>
        /// <param name="workbook"></param>
        /// <param name="sheetIndex"></param>
        /// <param name="firstRow"></param>
        /// <param name="lastRow"></param>
        /// <param name="firstCol"></param>
        /// <param name="lastCol"></param>
        public void MergeCells(IWorkbook workbook, int sheetIndex, int firstRow, int lastRow, int firstCol, int lastCol)
        {
            var sheet = workbook.GetSheetAt(sheetIndex);

            // 合并单元格
            var cellRangeAddress = new CellRangeAddress(firstRow, lastRow, firstCol, lastCol);
            sheet.AddMergedRegion(cellRangeAddress);

            // 可以对合并后的单元格设置样式
            var cell = sheet.GetRow(firstRow).GetCell(firstCol) ?? sheet.GetRow(firstRow).CreateCell(firstCol);
            var style = workbook.CreateCellStyle();
            style.Alignment = HorizontalAlignment.Center;
            cell.CellStyle = style; 
        }

        public void SetCellStyle(IWorkbook workbook, int sheetIndex, int rowIndex, int colIndex)
        {
            var sheet = workbook.GetSheetAt(sheetIndex);
            var cell = sheet.GetRow(rowIndex).GetCell(colIndex) ?? sheet.GetRow(rowIndex).CreateCell(colIndex);
            
            var style = workbook.CreateCellStyle();

            // 设置字体
            var font = workbook.CreateFont();
            font.FontHeightInPoints = 1;
            font.FontName = "Arial";
            font.IsBold = true;
            style.SetFont(font);

            // 设置边框
            style.BorderBottom = BorderStyle.Thin;
            style.BorderLeft = BorderStyle.Thin;
            style.BorderRight = BorderStyle.Thin;
            style.BorderTop = BorderStyle.Thin;

            // 设置背景颜色
            style.FillForegroundColor = IndexedColors.LightBlue.Index;
            style.FillPattern = FillPattern.SolidForeground;

            cell.CellStyle = style;
            cell.SetCellValue("示例文本内容");
        }
    }
}

测试代码

private ExcelTools excel = new ExcelTools();
string excelFileName = Properties.Settings.Default.SavePath + "/燃气报警器数据表格.xlsx";

// TODO: 生成保存数据
DataTable dt = new DataTable();
dt.Columns.Add("设备UUID", typeof(string));
dt.Columns.Add("SIM卡号", typeof(string));
dt.Columns.Add("设备型号", typeof(string));
dt.Columns.Add("网络型号", typeof(string));
dt.Columns.Add("生产日期", typeof(string));

DataRow dr = dt.NewRow();
dr["设备UUID"] = "2021886000001";
dr["SIM卡号"] = "86452215642112345675";
dr["设备型号"] = "单甲烷";
dr["网络型号"] = "NB-IoT";
dr["生产日期"] = DateTime.Now.ToString();
dt.Rows.Add(dr);

if (excelFileName.EndsWith(".xls") || excelFileName.EndsWith(".xlsx"))
{
    if (!File.Exists(excelFileName))
    {
        // TODO: 文件不存在创建文件
        excel.CreateNewExcel(excelFileName, dt);
    }
    else
    {
        // TODO: 将IMEI号写入个Excel表格,若已经写入过则不再写入,防止重复写入
        if (excel.SearchColumnExitsItem(excelFileName, label_imei.Content.ToString(), 0) == false)
        {
            excel.AppendDataToExistingExcel(excelFileName, dt);
        }
    }
}
else
{
    MessageBox.Show("请先设置表格文件保存!");
}


http://www.kler.cn/a/457136.html

相关文章:

  • 电子电气架构 --- 汽车电子电器设计概述
  • c# 快捷键模块
  • Cesium 实战 27 - 三维视频融合(视频投影)
  • 【JS】期约的Promise.all()和 Promise.race()区别
  • 绘制三元图、颜色空间图:R语言代码
  • Docker-构建自己的Web-Linux系统-镜像webtop:ubuntu-kde
  • PDB数据库解析:
  • C 语言中 strlen 函数的深入剖析
  • leetcdoe 1670.设计前中后队列
  • opencv与pyqt6结合例子
  • 用VBA自动更正错误的注释引用序号
  • python圣诞节简单寻宝小游戏
  • Unity功能模块一对话系统(2)打字机淡入效果
  • 喜报 | 擎创科技入围上海市优秀信创解决方案
  • Rancher V2.9.0 Docker安装教程
  • 神经网络入门实战:(二十二)只训练 (多层网络的) 指定层 / (单层网络的) 指定参数
  • 青少年编程与数学 02-005 移动Web编程基础 06课题、响应式设计
  • Web 漏洞之 CSRF 漏洞挖掘:攻防深度剖析
  • SelectionArea 实现富文本
  • 【源码 导入教程 文档 讲解】基于springboot校园新闻管理系统源码和论文
  • 【13】MySQL如何选择合适的索引?
  • 【GlobalMapper精品教程】091:根据指定字段融合图斑(字段值相同融合到一起)
  • C++学习指南
  • 初识MySQL · 库的操作
  • linux内核系列---网络
  • Java圣诞树