首页 > 其他分享 >构建Excel帮助类

构建Excel帮助类

时间:2023-03-08 14:13:38浏览次数:37  
标签:帮助 digit int hssfworkbook Excel ICellStyle private 构建 BorderStyle

开发环境:.Net Core 3.1,NPOI 2.6.0

using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using NPOI.SS.Util;
using NPOI.XSSF.UserModel;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;

namespace XXXX.Util
{
    /// <summary>
    /// <para>创 建:Hou</para>
    /// <para>日 期:2022年9月7日11:43:55</para>
    /// <para>描 述:生成excel帮助类</para>
    /// </summary>
    public class ExcelHelper
    {
        #region 类属性
        private string tempfile = null;//模板绝对地址
        private string savefile = null;//保存excel文件绝对地址
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="tempfile">模板绝对地址</param>
        /// <param name="savefile">保存excel文件绝对地址</param>
        public ExcelHelper(string tempfile, string savefile)
        {
            this.tempfile = @tempfile;
            this.savefile = @savefile;
            string directory = this.savefile.Substring(0, this.savefile.LastIndexOf("\\"));
            if (!Directory.Exists(directory))
            {
                Directory.CreateDirectory(directory);
            }
        }
        /**
         * Excel 列号转数字
         *
         * @param excelNum Excel 列号
         * @return 数字
         */
        private int excelNum2Digit(string excelNum)
        {
            char[] chs = excelNum.ToCharArray();
            int digit = 0;

            /*
             *   B*26^2 + C*26^1 + F*26^0
             * = ((0*26 + B)*26 + C)*26 + F
             */
            foreach (char ch in chs)
            {
                digit = digit * 26 + (ch - 'A' + 1);
            }
            return digit;
        }

        /**
         * 数字转 Excel 列号
         *
         * @param digit 数字
         * @return Excel 列号
         */
        private string digit2ExcelNum(int digit)
        {
            /*
             * 找到 digit 所处的维度 len, 它同时表示字母的位数
             * power 表示 26^n, 这里 n 分别等于 1, 2, 3
             * pre 表示 前 n 个维度的总和, 即 26^1 + 26^2 + 26^3
             */
            int len = 0, power = 1, pre = 0;
            for (; pre < digit; pre += power)
            {
                power *= 26;
                len++;
            }
            // 确定字母位数
            char[] excelNum = new char[len];
            /*
             * pre 包含 digit 所处的维度
             * pre - power 则是 digit 前面的维度总和
             * digit 先减去前面维度和
             */
            digit -= pre - power;
            /*
             * 比较难以理解的是这里为什么要自减 1
             * 其实是相对 (digit / power + 'A') 这句代码来的
             * 本应该是 (digit / power + 'A' - 1),
             * digit / power 的结果是完整的维度个数, 它加上 'A' - 1 后需要再加一
             * 当最后剩下的 6 个加上 'A' - 1 是应当的, 不需要做修改
             * 而当 (digit / power + 'A') 中没有减 1 后,
             * digit / power 的结果不需要再加一了
             * 相对于 digit / power 的结果, 最后剩下的 6 需要减 1
             */
            digit--;
            for (int i = 0; i < len; i++)
            {
                power /= 26;
                excelNum[i] = (char)(digit / power + 'A');
                digit %= power;
            }
            return excelNum.ToString();
        }

        /// <summary>
        /// xlsx绑定基础数据
        /// </summary>
        /// <param name="ws"></param>
        /// <param name="dc"></param>
        private void BindDC(ref XSSFSheet ws, Dictionary<string, string> dc)
        {
            foreach (string item in dc.Keys)
            {
                string[] items = item.Split("-");
                if (items.Length == 2)
                {
                    ws.GetRow(items[1].ParseToInt() - 1).GetCell(excelNum2Digit(items[0]) - 1).SetCellValue(dc[item]);
                }
            }
        }
        /// <summary>
        /// xls绑定基础数据
        /// </summary>
        /// <param name="ws"></param>
        /// <param name="dc"></param>
        private void BindDC(ref HSSFSheet ws, Dictionary<string, string> dc)
        {
            foreach (string item in dc.Keys)
            {
                string[] items = item.Split("-");
                if (items.Length == 2)
                {
                    ws.GetRow(items[1].ParseToInt() - 1).GetCell(excelNum2Digit(items[0]) - 1).SetCellValue(dc[item]);
                }
            }
        }
        /// <summary>
        /// xlsx保存文件
        /// </summary>
        /// <param name="ws"></param>
        /// <param name="workbook"></param>
        /// <param name="result"></param>
        private void SaveFile(ref XSSFSheet ws, XSSFWorkbook workbook, ref TData result)
        {
            ws.ForceFormulaRecalculation = true;//保存文件
            using (FileStream filess = File.OpenWrite(savefile))
            {
                workbook.Write(filess);
            }
            result.Message = savefile;
            result.Tag = 1;

        }

        /// <summary>
        /// xls保存文件
        /// </summary>
        /// <param name="ws"></param>
        /// <param name="workbook"></param>
        /// <param name="result"></param>
        private void SaveFile(ref HSSFSheet ws, HSSFWorkbook workbook, ref TData result)
        {
            ws.ForceFormulaRecalculation = true;//保存文件
            using (FileStream filess = File.OpenWrite(savefile))
            {
                workbook.Write(filess);
            }
            result.Message = savefile;
            result.Tag = 1;

        }


        /// <summary>
        /// 复制行格式并插入指定行数
        /// </summary>
        /// <param name="sheet">当前sheet</param>
        /// <param name="sourceRowIndex">模板行位置</param>
        /// <param name="startRowIndex">起始行位置</param>
        /// <param name="insertCount">插入行数</param>
        public void CopyRow(XSSFWorkbook workbook, ISheet sheet, int sourceRowIndex, int startRowIndex, int insertCount)
        {
            IRow sourceRow = sheet.GetRow(sourceRowIndex);
            int sourceCellCount = sourceRow.Cells.Count;
            //处理如果是最后一行,直接使用移动语法会报空指针,这里处理一下最后一行的特殊情况
            if (startRowIndex > sheet.LastRowNum)
            {
                for (int i = 0; i < insertCount; i++)
                {
                    sheet.CreateRow(startRowIndex + i);
                }
            }
            //1. 批量移动行,清空插入区域
            sheet.ShiftRows(startRowIndex, //开始行
                            sheet.LastRowNum, //结束行
                            insertCount, //插入行总数
                            true,        //是否复制行高
                            false        //是否重置行高
                            );
            Dictionary<int, int> dic_mer = new Dictionary<int, int>();
            int m = 0;
            while (m < sourceRow.LastCellNum)
            {
                ICell sourceCell = sourceRow.GetCell(m);
                if (sourceCell == null)
                    continue;
                if (sourceCell.IsMergedCell)
                {
                    dic_mer.Add(m, GetLastCol(sheet, sourceRowIndex, m));
                    m = dic_mer[m] + 1;
                }
                else
                {
                    dic_mer.Add(m, -1);
                    m++;
                }
            }

            for (int i = startRowIndex; i < startRowIndex + insertCount; i++)
            {
                m = 0;
                IRow targetRow = null;
                ICell sourceCell = null;
                ICell targetCell = null;
                targetRow = sheet.CreateRow(i);
                targetRow.Height = sourceRow.Height;//复制行高
                while (m < sourceRow.LastCellNum)
                {
                    sourceCell = sourceRow.GetCell(m);
                    targetCell = targetRow.CreateCell(m, sourceCell.CellType);
                    targetCell.CellStyle = sourceCell.CellStyle;//赋值单元格格式
                    m++;
                }
                foreach (int item in dic_mer.Keys)
                {
                    sourceCell = sourceRow.GetCell(item);
                    targetCell = targetRow.CreateCell(item, sourceCell.CellType);
                    targetCell.CellStyle = sourceCell.CellStyle;//赋值单元格格式
                    if (dic_mer[item] > 0)
                    {
                        sheet.AddMergedRegion(new CellRangeAddress(i, i, item, dic_mer[item]));
                    }
                }
            }


        }
        /// <summary>
        /// 获取合并行的最后的列下标
        /// </summary>
        /// <param name="sheet"></param>
        /// <param name="row"></param>
        /// <param name="column"></param>
        /// <returns></returns>
        private int GetLastCol(ISheet sheet, int row, int column)
        {
            for (int i = 0; i < sheet.NumMergedRegions; i++)
            {
                CellRangeAddress range = sheet.GetMergedRegion(i);
                if (range != null && range.FirstColumn == column && range.FirstRow == row)
                {
                    return range.LastColumn;
                }
            }
            return -1;
        }

        /// <summary>
        /// 删除某行所有的合并单元格
        /// </summary>
        /// <param name="sheet"></param>
        /// <param name="rowIndex"></param>
        private void RemoveMergedRegion(ISheet sheet, int rowIndex)
        {
            int MergedCount = sheet.NumMergedRegions;
            for (int i = MergedCount - 1; i >= 0; i--)
            {
                /**
                    CellRangeAddress对象属性有:FirstColumn,FirstRow,LastColumn,LastRow 进行操作 取消合并单元格
                **/
                var temp = sheet.GetMergedRegion(i);
                if (temp != null && temp.FirstRow == rowIndex)
                {
                    sheet.RemoveMergedRegion(i);
                }
            }
        }
        #endregion

        #region 样式区
        /// <summary>
        /// 自定义的样式
        /// </summary>
        /// <returns></returns>
        private ICellStyle styleOne(HSSFWorkbook hssfworkbook)
        {
            ICellStyle styleOne = hssfworkbook.CreateCellStyle();
            styleOne.BorderBottom = BorderStyle.Thick;
            styleOne.BorderLeft = BorderStyle.Thick;
            styleOne.BorderRight = BorderStyle.Thick;
            styleOne.BorderTop = BorderStyle.Thick;
            styleOne.VerticalAlignment = VerticalAlignment.Center;
            //styleOne.FillBackgroundColor = 244;
            styleOne.WrapText = true;
            NPOI.SS.UserModel.IFont font = hssfworkbook.CreateFont();
            font.FontHeight = 16 * 16;
            font.Boldweight = 700;
            styleOne.SetFont(font);
            return styleOne;
        }
        /// <summary>
        /// 垂直居中
        /// </summary>
        /// <param name="hssfworkbook"></param>
        /// <returns></returns>
        private ICellStyle style0(HSSFWorkbook hssfworkbook)
        {
            ICellStyle style0 = hssfworkbook.CreateCellStyle();
            style0.VerticalAlignment = VerticalAlignment.Center;
            return style0;
        }

        /// <summary>
        /// 四周薄边框
        /// </summary>
        /// <param name="hssfworkbook"></param>
        /// <returns></returns>
        private ICellStyle style1(HSSFWorkbook hssfworkbook)
        {
            ICellStyle style1 = hssfworkbook.CreateCellStyle();
            style1.BorderBottom = BorderStyle.Thin;
            style1.BorderLeft = BorderStyle.Thin;
            style1.BorderRight = BorderStyle.Thin;
            style1.BorderTop = BorderStyle.Thin;
            style1.VerticalAlignment = VerticalAlignment.Center;
            return style1;
        }

        /// <summary>
        /// 四周厚边框
        /// </summary>
        /// <param name="hssfworkbook"></param>
        /// <returns></returns>
        private ICellStyle style2(HSSFWorkbook hssfworkbook)
        {
            ICellStyle style2 = hssfworkbook.CreateCellStyle();
            style2.BorderBottom = BorderStyle.Thick;
            style2.BorderLeft = BorderStyle.Thick;
            style2.BorderRight = BorderStyle.Thick;
            style2.BorderTop = BorderStyle.Thick;
            style2.VerticalAlignment = VerticalAlignment.Center; return style2;
        }
        /// <summary>
        /// 顶部厚边框
        /// </summary>
        /// <param name="hssfworkbook"></param>
        /// <returns></returns>
        private ICellStyle style3(HSSFWorkbook hssfworkbook)
        {
            ICellStyle style3 = hssfworkbook.CreateCellStyle();
            style3.BorderTop = BorderStyle.Thick;
            style3.BorderRight = BorderStyle.Thin;
            style3.VerticalAlignment = VerticalAlignment.Center;
            return style3;
        }

        /// <summary>
        /// 右部厚边框
        /// </summary>
        /// <param name="hssfworkbook"></param>
        /// <returns></returns>
        private ICellStyle style4(HSSFWorkbook hssfworkbook)
        {
            ICellStyle style4 = hssfworkbook.CreateCellStyle();
            style4.BorderRight = BorderStyle.Thick;
            style4.VerticalAlignment = VerticalAlignment.Center;
            return style4;
        }

        /// <summary>
        /// 左部厚边框
        /// </summary>
        /// <param name="hssfworkbook"></param>
        /// <returns></returns>
        private ICellStyle style5(HSSFWorkbook hssfworkbook)
        {
            ICellStyle style5 = hssfworkbook.CreateCellStyle();
            style5.BorderLeft = BorderStyle.Thick;
            style5.BorderRight = BorderStyle.Thin;
            style5.VerticalAlignment = VerticalAlignment.Center; return style5;
        }

        /// <summary>
        /// 底部厚边框
        /// </summary>
        /// <param name="hssfworkbook"></param>
        /// <returns></returns>
        private ICellStyle style6(HSSFWorkbook hssfworkbook)
        {
            ICellStyle style6 = hssfworkbook.CreateCellStyle();
            style6.BorderTop = BorderStyle.Thin;
            style6.BorderBottom = BorderStyle.Thick;
            style6.BorderRight = BorderStyle.Thin;
            style6.VerticalAlignment = VerticalAlignment.Center;
            return style6;
        }
        /// <summary>
        /// 文字上对齐
        /// </summary>
        /// <param name="hssfworkbook"></param>
        /// <returns></returns>
        private ICellStyle style7(HSSFWorkbook hssfworkbook)
        {
            ICellStyle style7 = hssfworkbook.CreateCellStyle();
            style7.Alignment = NPOI.SS.UserModel.HorizontalAlignment.Center;
            style7.VerticalAlignment = VerticalAlignment.Top;
            return style7;
        }


        #endregion

    }
}

这个Excel帮助类大部分都是从网络上或者官网示例中提取来的,只有方法(CopyRow复制行格式并插入指定行数),是单独写的,为了满足以下情况而设计的:

需求:模板中定义好的字体、边框之类的基础设置,毕竟在代码中去设置字体等格式太麻烦,所以我一般都是写好示例行,然后绑定数据时复制行。例如这里插入的数据按照列名的样式即可,不用单独建立一个示例行了,

最终数据图

标签:帮助,digit,int,hssfworkbook,Excel,ICellStyle,private,构建,BorderStyle
From: https://www.cnblogs.com/oBehavior/p/17191800.html

相关文章

  • 软著申请模板,帮助了不少小伙伴少走弯路
    大家好,我是小悟说话题之前,先分享一件对我来说值得分享的事情,那就是又有一张软件著作权证书申请通过了,目前是待发放的状态,也就是说材料已经审核通过,等待发放邮寄出去了。话说......
  • JAVA 实现导入导出Excel-随笔
    1、开个小差今天是我第一次使用博客园记录随笔内容;从-CSDN->Typora->语雀其中的转换过程中,让我清楚这三个工具都比博客园记录随笔要轻松的多;话又说回来,那么我又为什么......
  • 构建samba共享文件服务器
    构建samba共享文件服务器拓扑图:实验需求:创建组名字benet,创建bob、tom、alice、marry将用户添加到benet,组安装samba服务器,bob、tom、alice为普通账户marry为管理员对所有目录......
  • 缓存+数据库构建高可靠的扣减方案
    数据库和纯缓存实现的扣减方案数据库方案的性能较差;纯缓存方案虽不会导致超卖,但因缓存不具备事务特性,极端情况下会存在缓存里的数据无法回滚,导致出现少卖的情况。......
  • 把excel六位日期中间加上横线的公式
     同事希望把Excel六位日期中间加上减号"-",我为她设计了这样一个公式,调试完成后双击G2单元格右下方的填充柄,整列都跟着设置好了。思路:左边四位加横杠,加右四位的左二位,......
  • openpyxl-excel文件处理
    importos.path#加载对象fromopenpyxlimportWorkbookfromopenpyxlimportload_workbook#设置样式fromopenpyxl.stylesimportFontfromopenpyxl.stylesimpo......
  • #yyds干货盘点#【愚公系列】2023年03月 .NET CORE工具案例-.NET Core使用MiniExcel
    前言1.MiniExcel的介绍MiniExcel是一个简单、高效避免OOM的.NET处理Excel查、写、填充数据工具。目前主流框架大多需要将数据全载入到内存方便操作,但这会导致内......
  • ExcelPatternTool: Excel表格-数据库互导工具
    ExcelPatternToolExcel表格-数据库互导工具介绍:指定Pattern文件-一个规则描述的json文档,基于此规则实现Excel表格与数据库之间的导入导出,校验等功能。特点:小巧,轻量......
  • Go构建遇到cgo动态库时解决方案
    1.问题golang构建程序很简单,当遇到需要调用c库时,如通常使用net,kafka,sqlite3程序运行时就会调用当前服务器的动态库,如果遇到没有库时,通常还需要下载比如alpine......
  • 使用NineData构建任意时间点(PITR)数据恢复能力
    在当前数字化经济的时代下,数据成为企业的关键资产。但因数据误删、服务器故障、入侵等原因导致数据丢失影响业务,会对公司造成重大损失,所以如何保证数据资产的安全、稳定及可......