zoukankan      html  css  js  c++  java
  • NPOI封装类

    // /// <summary>
        /// Excel操作类
        /// </summary>
        public class NPOIHelper : IDisposable
        {
            private string fileALLPath = "";//Excel物理路径(绝对路径)
            private IWorkbook workbook = null;//使用NPOI初始化的Excel工作簿
            private FileStream fs = null;//Excel文件流
            private bool disposed;
            private string rowsCode = "<%ROWS:{0}%>";//数据行绑定码
            
            public NPOIHelper()
            {
                disposed = false;
            }
    
            public NPOIHelper(string fileALLPath)
            {
                this.fileALLPath = fileALLPath;
                disposed = false;
                //使用NPOI初始化的Excel工作簿
                this.fs = new FileStream(fileALLPath, FileMode.Open, FileAccess.Read);
                if (fileALLPath.IndexOf(".xlsx") > 0)
                {
                    workbook = new XSSFWorkbook(fs);
                }
                else if (fileALLPath.IndexOf(".xls") > 0)
                {
                    workbook = new HSSFWorkbook(fs);
                }
            }
    
            /// <summary>
            /// 将DataTable数据导入到excel中
            /// </summary>
            /// <param name="data">要导入的数据</param>
            /// <param name="isColumnWritten">DataTable的列名是否要导入</param>
            /// <param name="sheetName">要导入的excel的sheet的名称</param>
            /// <returns>导入数据行数(包含列名那一行)</returns>
            public int DataTableToExcel(DataTable data, string sheetName, bool isColumnWritten)
            {
                int i = 0;
                int j = 0;
                int count = 0;
                ISheet sheet = null;
    
                fs = new FileStream(fileALLPath, FileMode.OpenOrCreate, FileAccess.ReadWrite);
                if (fileALLPath.IndexOf(".xlsx") > 0) // 2007版本
                    workbook = new XSSFWorkbook();
                else if (fileALLPath.IndexOf(".xls") > 0) // 2003版本
                    workbook = new HSSFWorkbook();
    
                try
                {
                    if (workbook != null)
                    {
                        sheet = workbook.CreateSheet(sheetName);
                    }
                    else
                    {
                        return -1;
                    }
    
                    if (isColumnWritten == true) //写入DataTable的列名
                    {
                        IRow row = sheet.CreateRow(0);
                        for (j = 0; j < data.Columns.Count; ++j)
                        {
                            row.CreateCell(j).SetCellValue(data.Columns[j].ColumnName);
                        }
                        count = 1;
                    }
                    else
                    {
                        count = 0;
                    }
    
                    for (i = 0; i < data.Rows.Count; ++i)
                    {
                        IRow row = sheet.CreateRow(count);
                        for (j = 0; j < data.Columns.Count; ++j)
                        {
                            row.CreateCell(j).SetCellValue(data.Rows[i][j].ToString());
                        }
                        ++count;
                    }
                    workbook.Write(fs); //写入到excel
                    return count;
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Exception: " + ex.Message);
                    return -1;
                }
            }
    
            /// <summary>
            /// 将excel中的数据导入到DataTable中
            /// </summary>
            /// <param name="sheetName">excel工作薄sheet的名称</param>
            /// <param name="isFirstRowColumn">第一行是否是DataTable的列名</param>
            /// <returns>返回的DataTable</returns>
            public DataTable ExcelToDataTable(string sheetName, bool isFirstRowColumn)
            {
                ISheet sheet = null;
                DataTable data = new DataTable();
                int startRow = 0;
                try
                {
                    fs = new FileStream(fileALLPath, FileMode.Open, FileAccess.Read);
                    if (fileALLPath.IndexOf(".xlsx") > 0) // 2007版本
                        workbook = new XSSFWorkbook(fs);
                    else if (fileALLPath.IndexOf(".xls") > 0) // 2003版本
                        workbook = new HSSFWorkbook(fs);
    
                    if (sheetName != null)
                    {
                        sheet = workbook.GetSheet(sheetName);
                        if (sheet == null) //如果没有找到指定的sheetName对应的sheet,则尝试获取第一个sheet
                        {
                            sheet = workbook.GetSheetAt(0);
                        }
                    }
                    else
                    {
                        sheet = workbook.GetSheetAt(0);
                    }
    
                    if (sheet != null)
                    {
                        IRow firstRow = sheet.GetRow(0);
                        int cellCount = firstRow.LastCellNum; //一行最后一个cell的编号 即总的列数
    
                        if (isFirstRowColumn)
                        {
                            for (int i = firstRow.FirstCellNum; i < cellCount; ++i)
                            {
                                ICell cell = firstRow.GetCell(i);
                                if (cell != null)
                                {
                                    string cellValue = cell.StringCellValue;
                                    if (cellValue != null)
                                    {
                                        DataColumn column = new DataColumn(cellValue);
                                        data.Columns.Add(column);
                                    }
                                }
                            }
                            startRow = sheet.FirstRowNum + 1;
                        }
                        else
                        {
                            startRow = sheet.FirstRowNum;
                        }
    
                        //最后一列的标号
                        int rowCount = sheet.LastRowNum;
                        for (int i = startRow; i <= rowCount; ++i)
                        {
                            IRow row = sheet.GetRow(i);
                            if (row == null) continue; //没有数据的行默认是null       
    
                            DataRow dataRow = data.NewRow();
                            for (int j = row.FirstCellNum; j < cellCount; ++j)
                            {
                                if (row.GetCell(j) != null) //同理,没有数据的单元格都默认是null
                                    dataRow[j] = row.GetCell(j).ToString();
                            }
                            data.Rows.Add(dataRow);
                        }
                    }
    
                    return data;
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Exception: " + ex.Message);
                    return null;
                }
            }
    
            /// <summary>
            /// 获取Excel中Sheet名称集合
            /// </summary>
            /// <returns></returns>
            public string[] SheetNames()
            {
                fs = new FileStream(fileALLPath, FileMode.Open, FileAccess.Read);
                if (fileALLPath.IndexOf(".xlsx") > 0) // 2007版本
                    workbook = new XSSFWorkbook(fs);
                else if (fileALLPath.IndexOf(".xls") > 0) // 2003版本
                    workbook = new HSSFWorkbook(fs);
                int sheetCount = workbook.NumberOfSheets;
                string[] sheetName = new string[sheetCount];//保存表的名称
                for (int i = 0; i < sheetCount; i++)
                {
                    sheetName[i] = workbook.GetSheetName(i);
                }
                return sheetName;
            }
    
            /// <summary>
            /// 删除指定的Sheets
            /// </summary>
            public void RemoveSheetsByNames(string[] sheetNames)
            {
                foreach (string sheetName in sheetNames)
                {
                    ISheet sheet = workbook.GetSheet(sheetName);
                    int index = workbook.GetSheetIndex(sheet);
                    workbook.RemoveSheetAt(index);
                }
            }
    
            /// <summary>
            /// 保存修改后的excel
            /// </summary>
            public void Save()
            {
                FileStream fileSave = new FileStream(fileALLPath, FileMode.Open, FileAccess.Write);
                workbook.Write(fileSave);
                fileSave.Close();
            }
    
            /// <summary>
            /// 填充Sheet
            /// </summary>
            /// <param name="sheetName">sheet名称</param>
            /// <param name="dt">数据源(DataTable)</param>
            /// <param name="isList">填充类型:"对象"还是"集合",true:"集合",false:"对象"</param>
            /// <param name="dtName">DataTable TableName</param>
            /// <param name="isAlarm">是否是:业务风险提示</param>
            /// <param name="rowIndex">遍历Excel范围:行数,默认30行</param>
            /// <param name="colIndex">遍历Excel范围:列数,默认20列</param>
            public void FillSheet(string sheetName, DataTable dt, bool isList, string dtName = "", bool isAlarm = false, int rowIndex = 30, int colIndex = 20)
            {
                if (dt == null || dt.Rows.Count <= 0)
                    return;
    
                ISheet sheet = workbook.GetSheet(sheetName);
                if (sheet == null)
                    return;
    
                if (!isList)
                {
                    //"对象填充"
                    foreach (DataColumn column in dt.Columns)
                    {
                        for (int rowIn = 0; rowIn < rowIndex; rowIn++)
                        {
                            for (int colIn = 0; colIn < colIndex; colIn++)
                            {
                                IRow row = sheet.GetRow(rowIn);
                                if (row == null)
                                    continue;
                                ICell cell = row.GetCell(colIn);
                                if (cell == null)
                                    continue;
    
                                if (string.IsNullOrEmpty(dtName))
                                {
                                    dtName = dt.TableName;
                                }
                                string a = string.Empty;
                                if (isAlarm)
                                {
                                    a = "$" + column.ColumnName;
                                }
                                else
                                {
                                    a = "<%" + dtName + ";" + column.ColumnName + "%>";
                                }
                                if (cell.ToString() == a)
                                {
                                    var value = dt.Rows[0][column.ColumnName];
    
                                    if (value == DBNull.Value || value == null)
                                    {
                                        cell.SetCellValue(string.Empty);
                                    }
                                    else
                                    {
                                        if (column.DataType.FullName == "System.DateTime")
                                        {
                                            cell.SetCellValue(Convert.ToDateTime(value).ToString("yyyy-MM-dd"));
                                        }
                                        else if (column.DataType.FullName == "System.Decimal")
                                        {
                                            cell.SetCellValue(double.Parse(Convert.ToDecimal(value).ToString("N2")));
                                        }
                                        else
                                        {
                                            cell.SetCellValue(value.ToString());
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                else
                {
                    //"集合"填充
                    ICellStyle style = workbook.CreateCellStyle();
                    style.BorderBottom = BorderStyle.Thin;
                    style.BorderLeft = BorderStyle.Thin;
                    style.BorderRight = BorderStyle.Thin;
                    style.BorderTop = BorderStyle.Thin;
    
                    for (int i = 0; i < dt.Rows.Count; i++)
                    {
                        IRow row = sheet.CreateRow(i + 1);
                        for (int j = 0; j < dt.Columns.Count; j++)
                        {
                            ICell cell = row.CreateCell(j);
                            cell.SetCellValue(dt.Rows[i][j].ToString());
                            cell.CellStyle = style;
                        }
                    }
                }
                sheet.ForceFormulaRecalculation = true;//刷新单元格公式,自动计算
            }
    
            /// <summary>
            /// 填充Sheet数据(对多Table数据填充)
            /// </summary>
            /// <param name="sheetName">sheet名称</param>
            /// <param name="tableNum">table个数</param>
            /// <param name="tableNames">table的表名(用于匹配数据源中的table和数据模板中数据绑定码</param>
            /// <param name="cellKeys">table的数据列名(用于匹配数据源中对应列数据),如:{{"fieldName1,fliedName2"},{"fieldName1,fieldName2,fieldName3"}},字段名之间使用 , 分割</param>
            /// <param name="dts">数据源</param>
            /// <param name="cellCount">数据列数,默认为0,取第一行的数据列数</param>
            /// <param name="isSum">是否求和,默认不求和。如果为true,会搜索“合计”行,把数据类型为decimal的列求和</param>
            public void FillSheetEx(string sheetName, int tableNum, string[] tableNames, string[] cellKeys, DataSet dts, int cellCount = 0, bool isSum = false)
            {
                if (dts == null || dts.Tables.Count <= 0)
                {
                    return;
                }
    
                ISheet sheet = workbook.GetSheet(sheetName);
                if (sheet == null)
                {
                    return;
                }
    
                if (sheet != null)
                {
                    if (cellCount == 0)
                    {
                        cellCount = sheet.GetRow(0).LastCellNum;//列数
                    }
                    int searchRow = 0;//搜索开始行
                    int startRow = 0;
                    int startCell = 0;
                    string content = "";
                    for (int i = 0; i < tableNum; i++)
                    {
                        content = string.Format(rowsCode, tableNames[i]);//数据绑定码
                        MatchSheetContent(sheet, content, out startRow, out startCell, cellCount, 5, searchRow);//获取插入数据的行和列
                        if (startRow > 0)
                        {
                            sheet.GetRow(startRow).GetCell(startCell).SetCellValue("");//清空数据绑定码信息
                            InsertSheetData(sheet, dts.Tables[tableNames[i]], startRow, dts.Tables[tableNames[i]].Columns.Count, cellKeys[i].Split(','), isSum);//插入数据
    
                            searchRow = startRow + dts.Tables[tableNames[i]].Rows.Count + 3; //3:表和表之间隔2行
                            if (isSum)
                            {
                                searchRow = searchRow + 1;//合计的1行
                            }
                        }
                        else
                        {
                            continue;
                        }
                    }
                }
                sheet.ForceFormulaRecalculation = true;//刷新单元格公式,自动计算
            }
    
            /// <summary>
            /// 下载Excel
            /// </summary>
            /// <param name="fileName">下载时,显示的文件名</param>
            public void Download(string fileName)
            {
                FileStream fs = new FileStream(fileName, FileMode.Open);
                byte[] bytes = new byte[(int)fs.Length];
                fs.Read(bytes, 0, bytes.Length);
                fs.Close();
                System.Web.HttpContext.Current.Response.ContentType = "application/octet-stream;charset=gb2312";
                System.Web.HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment; filename=" + System.Web.HttpUtility.UrlEncode(fileName, System.Text.Encoding.UTF8));
                System.Web.HttpContext.Current.Response.BinaryWrite(bytes);
                System.Web.HttpContext.Current.Response.Flush();
                System.Web.HttpContext.Current.ApplicationInstance.CompleteRequest();
            }
    
            /// <summary>
            /// 直接下载Excel文件
            /// </summary>
            /// <param name="fileName"></param>
            public void DownloadEx(string fileName)
            {
                int length = (int)fs.Length;
                byte[] data = new byte[length];
                fs.Position = 0;
                fs.Read(data, 0, length);
                fs.Close();
                byte[] buffer;
                using (MemoryStream ms = new MemoryStream(data))
                {
                    buffer = new byte[ms.Capacity];
                    if (ms.CanRead)
                    {
                        ms.Read(buffer, 0, ms.Capacity);
                    }
                }
    
                System.Web.HttpContext.Current.Response.Clear();
                System.Web.HttpContext.Current.Response.ContentType = "application/octet-stream;charset=gb2312";
                System.Web.HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment; filename=" + System.Web.HttpUtility.UrlEncode(fileName, System.Text.Encoding.UTF8));
                System.Web.HttpContext.Current.Response.BinaryWrite(buffer);
                System.Web.HttpContext.Current.Response.Flush();
                System.Web.HttpContext.Current.ApplicationInstance.CompleteRequest();
            }
    
            public void Dispose()
            {
                Dispose(true);
                GC.SuppressFinalize(this);
            }
    
            protected virtual void Dispose(bool disposing)
            {
                if (!this.disposed)
                {
                    if (disposing)
                    {
                        if (fs != null)
                            fs.Close();
                    }
    
                    fs = null;
                    disposed = true;
                }
            }
    
            #region 其他成员方法
            /// <summary>
            /// 在sheet中的某个单元格设置计算函数(会导致Excel文件错误,方法待优化)
            /// </summary>
            /// <param name="sheetName"></param>
            /// <param name="rowIndex">设置单元格行索引</param>
            /// <param name="cellIndex">设置单元格列索引</param>
            /// <param name="operatorCode">函数名</param>
            /// <param name="startRowIndex">开始行索引</param>
            /// <param name="startCellIndex">开始列索引</param>
            /// <param name="endRowIndex">结束行索引</param>
            /// <param name="endCellIndex">结束列索引</param>
            ///  <param name="dataFormat">默认:194:数值格式</param>
            public void OperatorFormula(string sheetName, int rowIndex, int cellIndex, string operatorCode, int startRowIndex, int startCellIndex, int endRowIndex, int endCellIndex, short dataFormat = 194)
            {
                ISheet sheet = workbook.GetSheet(sheetName);
                if (sheet == null)
                {
                    return;
                }
                string strFormula = GetOperatorFormula(operatorCode, startRowIndex, startCellIndex, endRowIndex, endCellIndex);
                ICell cell = sheet.GetRow(rowIndex).GetCell(cellIndex);
                cell.CellStyle.DataFormat = dataFormat;
                cell.SetCellType(CellType.Formula);
                cell.SetCellFormula(strFormula);
            }
            #endregion
    
            #region 扩展方法
            /// <summary>
            /// 下载服务器文件
            /// </summary>
            /// <param name="fileAllPath">文件全路径</param>
            /// <param name="fileName">下载文件名(包含扩展名)</param>
            public static void Download(string fileAllPath, string fileName)
            {
                if (!File.Exists(fileAllPath))
                {
                    return;
                }
                using (FileStream fs = new FileStream(fileAllPath, FileMode.Open))
                {
                    byte[] buffer = new byte[(int)fs.Length];
                    fs.Read(buffer, 0, buffer.Length);
                    fs.Close();
    
                    HttpContext.Current.Response.Clear();
                    HttpContext.Current.Response.ContentType = "application/octet-stream;charset=gb2312";
                    HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment; filename=" + System.Web.HttpUtility.UrlEncode(fileName, System.Text.Encoding.UTF8));
                    HttpContext.Current.Response.BinaryWrite(buffer);
                    HttpContext.Current.Response.Flush();
                    HttpContext.Current.ApplicationInstance.CompleteRequest();
                }
            }
    
            /// <summary>
            /// 下载数据文件
            /// </summary>
            /// <param name="workbook">Excel实体</param>
            /// <param name="fileName">下载文件名(包含扩展名)</param>
            public static void Download(HSSFWorkbook workbook, string fileName)
            {
                using (MemoryStream ms = new MemoryStream())
                {
                    workbook.Write(ms);
                    ms.Flush();
                    ms.Position = 0;
    
                    byte[] buffer = new byte[ms.Capacity];
                    if (ms.CanRead)
                    {
                        ms.Read(buffer, 0, ms.Capacity);
                    }
                    ms.Close();
    
                    HttpContext.Current.Response.Clear();
                    HttpContext.Current.Response.ContentType = "application/octet-stream;charset=gb2312";
                    HttpContext.Current.Response.AddHeader("Content-Disposition", "attachment; filename=" + HttpUtility.UrlEncode(fileName, Encoding.UTF8));
                    HttpContext.Current.Response.BinaryWrite(buffer);
                    HttpContext.Current.Response.Flush();
                    HttpContext.Current.ApplicationInstance.CompleteRequest();
                }
            }
    
            /// <summary>
            /// 创建单元格样式
            /// </summary>
            /// <param name="workbook"></param>
            /// <param name="type">单元格类型</param>
            /// <param name="fontHeightInPoints">字号,传0为默认字号</param>
            /// <param name="foregroundColor">背景色(可通过NPOI.HSSF.Util.HSSFColor获取色值)</param>
            /// <returns></returns>
            public static ICellStyle CreateCellStyle(HSSFWorkbook workbook, SheetCellType type, short fontHeightInPoints = 0, short foregroundColor = 0)
            {
                ICellStyle cellStyle = workbook.CreateCellStyle();
                switch (type.ToString())
                {
                    case "CellTitle":
                        #region 标题样式
                        //设置单元格边框
                        cellStyle.BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin;
                        cellStyle.BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin;
                        cellStyle.BorderRight = NPOI.SS.UserModel.BorderStyle.Thin;
                        cellStyle.BorderTop = NPOI.SS.UserModel.BorderStyle.Thin;
                        //设置单元格边框颜色
                        cellStyle.BottomBorderColor = HSSFColor.Black.Index;
                        cellStyle.LeftBorderColor = HSSFColor.Black.Index;
                        cellStyle.RightBorderColor = HSSFColor.Black.Index;
                        cellStyle.TopBorderColor = HSSFColor.Black.Index;
                        //设置水平垂直居中
                        cellStyle.VerticalAlignment = VerticalAlignment.Center;
                        cellStyle.Alignment = HorizontalAlignment.Center;
                        //设置单元格背景颜色
                        if (foregroundColor > 0)
                        {
                            cellStyle.FillForegroundColor = foregroundColor;
                            cellStyle.FillPattern = FillPattern.SolidForeground;//填充背景样式
                        }
                        //新建一个字体样式对象
                        IFont titleFont = workbook.CreateFont();
                        //字体大小13.5pt,对应像素18px
                        titleFont.FontHeightInPoints = 16;
                        //设置字体加粗样式
                        titleFont.Boldweight = short.MaxValue;
                        //使用SetFont方法将字体样式添加到单元格样式中 
                        cellStyle.SetFont(titleFont);
                        #endregion
                        break;
                    case "CellField":
                        #region 字段名样式
                        //设置单元格边框
                        cellStyle.BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin;
                        cellStyle.BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin;
                        cellStyle.BorderRight = NPOI.SS.UserModel.BorderStyle.Thin;
                        cellStyle.BorderTop = NPOI.SS.UserModel.BorderStyle.Thin;
                        //设置单元格边框颜色
                        cellStyle.BottomBorderColor = HSSFColor.Black.Index;
                        cellStyle.LeftBorderColor = HSSFColor.Black.Index;
                        cellStyle.RightBorderColor = HSSFColor.Black.Index;
                        cellStyle.TopBorderColor = HSSFColor.Black.Index;
                        //设置垂直水平居中
                        cellStyle.VerticalAlignment = VerticalAlignment.Center;
                        cellStyle.Alignment = HorizontalAlignment.Center;
                        //设置单元格背景颜色
                        if (foregroundColor > 0)
                        {
                            cellStyle.FillForegroundColor = foregroundColor;
                            cellStyle.FillPattern = FillPattern.SolidForeground;//填充背景样式
                        }
                        IFont FiledFont = workbook.CreateFont();
                        //字体大小10.5pt,对应像素14px
                        FiledFont.FontHeightInPoints = fontHeightInPoints <= 0 ? (short)10 : fontHeightInPoints;
                        //设置字体加粗样式
                        FiledFont.Boldweight = short.MaxValue;
                        cellStyle.SetFont(FiledFont);
                        #endregion
                        break;
                    case "CellValue":
                        #region 数据值样式
                        //设置单元格边框
                        cellStyle.BorderBottom = NPOI.SS.UserModel.BorderStyle.Thin;
                        cellStyle.BorderLeft = NPOI.SS.UserModel.BorderStyle.Thin;
                        cellStyle.BorderRight = NPOI.SS.UserModel.BorderStyle.Thin;
                        cellStyle.BorderTop = NPOI.SS.UserModel.BorderStyle.Thin;
                        //设置单元格边框颜色
                        cellStyle.BottomBorderColor = HSSFColor.Black.Index;
                        cellStyle.LeftBorderColor = HSSFColor.Black.Index;
                        cellStyle.RightBorderColor = HSSFColor.Black.Index;
                        cellStyle.TopBorderColor = HSSFColor.Black.Index;
                        //设置垂直水平居中
                        cellStyle.VerticalAlignment = VerticalAlignment.Center;
                        cellStyle.Alignment = HorizontalAlignment.Center;
                        //设置单元格背景颜色
                        if (foregroundColor > 0)
                        {
                            cellStyle.FillForegroundColor = foregroundColor;
                            cellStyle.FillPattern = FillPattern.SolidForeground;//填充背景样式
                        }
                        IFont valueFont = workbook.CreateFont();
                        //字体大小10.5pt,对应像素14px
                        valueFont.FontHeightInPoints = fontHeightInPoints <= 0 ? (short)9 : fontHeightInPoints;
                        cellStyle.SetFont(valueFont);
                        #endregion
                        break;
                }
                return cellStyle;
            }
    
            /// <summary>
            /// 合并及填充单元格
            /// </summary>
            /// <param name="sheet"></param>
            /// <param name="firstRow">第一行的index</param>
            /// <param name="lastRow">最后一行的index</param>
            /// <param name="firstCol">第一列的index</param>
            /// <param name="lastCol">最后一列的index</param>
            /// <param name="content">填充内容</param>
            /// <param name="cellHeight">单元格行高,默认高设置为0(标题一般传值:23.5f)</param>
            /// <param name="cellStyle">单元格样式接口实例</param>
            public static void MergeCell(HSSFSheet sheet, int firstRow, int lastRow, int firstCol, int lastCol, string content = "", float cellHeight = 0, ICellStyle cellStyle = null)
            {
                CellRangeAddress cellRange = new CellRangeAddress(firstRow, lastRow, firstCol, lastCol);
                sheet.AddMergedRegion(cellRange);
    
                //填充内容
                if (!string.IsNullOrWhiteSpace(content))
                {
                    IRow row = sheet.CreateRow(firstRow);
                    row.CreateCell(firstCol).SetCellValue(content);
                    //对应高度30px
                    if (cellHeight > 0)
                    {
                        row.Height = (short)(cellHeight * 20);
                    }
                }
    
                //合并单元格的样式
                for (int i = cellRange.FirstRow; i <= cellRange.LastRow; i++)
                {
                    IRow row = HSSFCellUtil.GetRow(i, sheet);
                    for (int j = cellRange.FirstColumn; j <= cellRange.LastColumn; j++)
                    {
                        ICell singleCell = HSSFCellUtil.GetCell(row, (short)j);
                        if (cellStyle != null)
                        {
                            singleCell.CellStyle = cellStyle;
                        }
                    }
                }
            }
    
            /// <summary>
            /// 设置表格自适应宽度
            /// </summary>
            /// <param name="sheet"></param>
            /// <param name="cellNum">表格列数</param>
            /// <param name="multiple">单元格显示宽度倍数(如1.5:是内容宽度的1.5倍),默认和内容宽度一致</param>
            /// <param name="defaultLen">数据为空时,单元格的默认填充长度:2</param>
            public static void SetAdaptiveWidth(HSSFSheet sheet, int cellNum, double multiple = 1, int defaultLen = 2)
            {
                int width = defaultLen * 1024;//空数据指定宽度
                int times = Convert.ToInt32(multiple * 10);
                for (int i = 0; i <= cellNum; i++)
                {
                    sheet.AutoSizeColumn(i);
                    if (sheet.GetColumnWidth(i) >= 2048)
                    {
                        width = sheet.GetColumnWidth(i);
                    }
                    sheet.SetColumnWidth(i, width * times / 10);
                }
            }
            #endregion
    
            #region 私有方法
            /// <summary>
            /// 向Sheet的指定行中插入数据
            /// </summary>
            /// <param name="sheet"></param>
            /// <param name="dt">数据源</param>
            /// <param name="startRowIndex">开始插入数据的行索引</param>
            /// <param name="cellCount">数据列数</param>
            /// <param name="cellKeys">列匹配关键字</param>
            /// <param name="isSum">是否求和,默认不求和。如果为true,会搜索“合计”行,把数据类型为decimal的列求和</param>
            private void InsertSheetData(ISheet sheet, DataTable dt, int startRowIndex, int cellCount, string[] cellKeys, bool isSum = false)
            {
                int firstDataRow = startRowIndex;
                sheet.ShiftRows(startRowIndex, sheet.LastRowNum, dt.Rows.Count - 1, true, false);
                string dataType = "";
                IRow row;
                for (int i = 0, len = dt.Rows.Count; i < len; i++)
                {
                    row = sheet.CreateRow(startRowIndex);
                    //创建列并插入数据
                    for (int index = 0; index < cellCount; index++)
                    {
                        ICellStyle cellStyle = sheet.GetRow(startRowIndex - 1).GetCell(i).CellStyle;//获取上一行的数据格式
                        dataType = dt.Rows[i][cellKeys[index]].GetType().ToString();
                        if (dataType == "System.DBNull")
                        {
                            row.CreateCell(index).SetCellValue("");
                        }
                        else if (dataType == "System.Decimal")
                        {
                            row.CreateCell(index).SetCellValue(double.Parse(Convert.ToDecimal(dt.Rows[i][cellKeys[index]]).ToString("N2")));
                        }
                        else if (dataType == "System.DateTime")
                        {
                            row.CreateCell(index).SetCellValue(Convert.ToDateTime(dt.Rows[i][cellKeys[index]]).ToString("yyyy-MM-dd"));
                        }
                        else
                        {
                            row.CreateCell(index).SetCellValue(!(dt.Rows[i][cellKeys[index]] is DBNull) ? dt.Rows[i][cellKeys[index]].ToString() : string.Empty);
                        }
                        row.GetCell(index).CellStyle = cellStyle;
                    }
                    startRowIndex = startRowIndex + 1;
                }
    
                if (isSum)//求和
                {
                    int startRow = 0;
                    int startCell = 0;
                    MatchSheetContent(sheet, "合计", out startRow, out startCell, cellCount, 5, startRowIndex);
                    if (startRow > 0)
                    {
                        IRow sumRow = sheet.GetRow(startRow);
                        for (int index = 0; index < dt.Columns.Count; index++)
                        {
                            if (sumRow.GetCell(index).CellType == CellType.Formula)//格式为表达式,求和
                            {
                                sumRow.GetCell(index).SetCellFormula(GetOperatorFormula("SUM", firstDataRow, index, startRow - 1, index));
                            }
                        }
                    }
                }
            }
    
            /// <summary>
            /// 获取Excel简单操作函数
            /// </summary>
            /// <param name="operatorCode">函数名,如:SUM</param>
            /// <param name="startRowIndex">开始行索引</param>
            /// <param name="startCellIndex">开始列索引</param>
            /// <param name="endRowIndex">结束行索引</param>
            /// <param name="endCellIndex">结束列索引</param>
            /// <returns></returns>
            private string GetOperatorFormula(string operatorCode, int startRowIndex, int startCellIndex, int endRowIndex, int endCellIndex)
            {
                string[,] code = { { "A" }, { "B" }, { "C" }, { "D" }, { "E" }, { "F" }, { "G" }, { "H" }, { "I" }, { "J" }, { "K" }, { "L" }, { "M" }, { "N" }, { "O" }, { "P" }, { "Q" }, { "R" }, { "S" }, { "T" }, { "U" }, { "V" }, { "W" }, { "X" }, { "Y" }, { "Z" } };
                string start = string.Format("{0}{1}", code[startCellIndex, 0], startRowIndex + 1);
                string end = string.Format("{0}{1}", code[endCellIndex, 0], endRowIndex + 1);
    
                return string.Format("{0}({1}:{2})", operatorCode, start, end);
            }
    
            /// <summary>
            /// 搜索Sheet中匹配信息的单元格所在行和列
            /// </summary>
            /// <param name="sheet"></param>
            /// <param name="matchContent">匹配信息</param>
            /// <param name="whichRow">返回信息:哪一行</param>
            /// <param name="whichCell">返回信息:哪一列</param>
            /// <param name="searchCells">搜索Sheet表格宽度,为0时默认取第一行的宽度</param>
            /// <param name="searchRows">搜索的行数,默认搜索5行</param>
            /// <param name="formWhichRow">从第几行开始搜索,默认从第一行</param>
            private void MatchSheetContent(ISheet sheet, string matchContent, out int whichRow, out int whichCell, int searchCells = 0, int searchRows = 5, int formWhichRow = 0)
            {
                whichRow = -1;
                whichCell = -1;
                IRow firstRow = sheet.GetRow(0);
                if (searchCells == 0)
                {
                    searchCells = firstRow.LastCellNum;//一行最后一个cell的编号 即总的列数
                }
    
                //遍历Sheet,找到需要填充数据源的行位置
                IRow currentRow;
                ICell currentCell;
                bool isFinish = false;
                for (int i = formWhichRow; i < formWhichRow + searchRows; i++)
                {
                    currentRow = sheet.GetRow(i);
                    for (int j = firstRow.FirstCellNum; j < searchCells; j++)
                    {
                        currentCell = currentRow.GetCell(j);
                        if (currentCell != null && currentCell.CellType == CellType.String)//仅检测字符串类型的单元格
                        {
                            string cellValue = currentCell.StringCellValue;
                            if (cellValue == matchContent)//找到需要填充数据的行
                            {
                                whichCell = currentCell.ColumnIndex;
                                whichRow = currentCell.RowIndex;
                                isFinish = true;
                                break;
                            }
                        }
                    }
    
                    if (isFinish)
                    {
                        break;
                    }
                }
            }
            #endregion
        }
    
        /// <summary>
        /// 单元格类型
        /// </summary>
        public enum SheetCellType
        {
            /// <summary>
            /// 标题
            /// </summary>
            CellTitle,
            /// <summary>
            /// 字段名
            /// </summary>
            CellField,
            /// <summary>
            /// 数据值
            /// </summary>
            CellValue
        }
    

      

  • 相关阅读:
    Spring mvc Data Redis—Pub/Sub(附Web项目源码)
    spring mvc Spring Data Redis RedisTemplate [转]
    征服 Nginx + Tomcat【转】
    Memcached笔记——(四)应对高并发攻击【转】
    征服 Redis + Jedis + Spring (三)—— 列表操作【转】
    iBatis自动生成的主键 (Oracle,MS Sql Server,MySQL)【转】
    OpenERP登录页面调整
    OpenERP QWeb模板标签笔记
    OpenERP Web开发
    ReadOnly field saved with NULL value
  • 原文地址:https://www.cnblogs.com/cdz-sky/p/10195437.html
Copyright © 2011-2022 走看看