zoukankan      html  css  js  c++  java
  • C# NOPI常用方法(记录老项目的方法)

    最近在维护公司的十年老项目。写了一些nopi的方法,记录一下。

            /// <summary>
            /// DataTable转成Excel表格
            /// </summary>
            /// <returns></returns>
            public static byte[] DataTableToExcel(DataTable dt)
            {
                using (HSSFWorkbook hssfworkbook = new HSSFWorkbook())//建立Excel 2003对象
                using (HSSFSheet sheet = (HSSFSheet)hssfworkbook.CreateSheet("sheet1"))//新建一个名称为sheet1的工作簿
                using (MemoryStream stream = new MemoryStream()) //二进制流中介
                {
                    DocumentSummaryInformation dsi = PropertySetFactory.CreateDocumentSummaryInformation();//配置文件属性
                    dsi.Company = string.Empty;
                    dsi.Category = string.Empty;//类别
                    dsi.Manager = string.Empty;//管理者
                    hssfworkbook.DocumentSummaryInformation = dsi;
                    SummaryInformation si = PropertySetFactory.CreateSummaryInformation();
                    si.Subject = string.Empty;//主题
                    si.Title = string.Empty;//标题
                    si.ApplicationName = string.Empty;//不知道是啥
                    si.Author = string.Empty;//作者
                    si.LastAuthor = string.Empty;//上一次保存者
                    si.Comments = string.Empty;//备注
                    si.CreateDateTime = DateTime.Now;
                    hssfworkbook.SummaryInformation = si;
    
                    //Func<HSSFWorkbook, string, short, HSSFCellStyle> setstyle =
                    //    (hssfwb, fontname, fontsize)
                    //     =>
                    //     {
                    //         HSSFFont font = (HSSFFont)hssfwb.CreateFont();
                    //         HSSFCellStyle style = (HSSFCellStyle)hssfwb.CreateCellStyle();
                    //         style.SetFont(font);
                    //         font.FontName = fontname;
                    //         font.FontHeightInPoints = fontsize;
                    //         return style;
                    //     };
    
                    ////表格设置
                    //sheet.SetColumnWidth(1, 30 * 256);//第二列较宽 
                    //sheet.DefaultColumnWidth = 13;
                    //HSSFCellStyle style0 = setstyle(hssfworkbook, "微软雅黑", 14);
                    //HSSFCellStyle style1 = setstyle(hssfworkbook, "微软雅黑", 12);
    
                    //设置列名
                    HSSFRow row = (HSSFRow)sheet.CreateRow(0);
                    for (int i = 0; i < dt.Columns.Count; i++)
                    {
                        Cell cell = row.CreateCell(i);
                        cell.SetCellValue(dt.Columns[i].ColumnName);
                        //cell.CellStyle = style0;
                    }
                    //单元格赋值
                    for (int i = 0; i < dt.Rows.Count; i++)
                    {
                        Row row1 = sheet.CreateRow(i + 1);
                        for (int j = 0; j < dt.Columns.Count; j++)
                        {
                            Cell cell = row1.CreateCell(j);
                            var value = dt.Rows[i][j];
                            if (value != null && value != DBNull.Value)
                            {
                                var valueType = value.GetType();
    
                                if (valueType == typeof(double) || valueType == typeof(decimal) || valueType == typeof(float) ||
                                    valueType == typeof(double?) || valueType == typeof(decimal?) || valueType == typeof(float?) ||
                                    valueType == typeof(byte) || valueType == typeof(int) || valueType == typeof(long) ||
                                    valueType == typeof(byte?) || valueType == typeof(int?) || valueType == typeof(long?)
                                    )
                                {
                                    cell.SetCellValue(Convert.ToDouble(value));
                                }
                                else
                                {
                                    cell.SetCellValue(value.ToString());
                                }
                            }
                            else
                            {
                                cell.SetCellValue(string.Empty);
                            }
                            //cell.CellStyle = style1;
                        }
                    }
                    hssfworkbook.Write(stream);
                    return stream.ToArray();
                }
            }
    
    //使用
    DataTable dt = GetDataTable();
    dt.TableName = "导出的Excel";
    DataTableToExcel(dt);
    
            /// <summary>
            /// 获取带数据的模版表格
            /// </summary>
            /// <param name="columns">Key为数据库的列名,Value为表格中显示的列名称。</param>
            /// <param name="templetePath">模版文件的路径</param>
            /// <param name="data">数据库中的数据</param>
            /// <returns></returns>
            public static byte[] GetDataTempleteExcel(Dictionary<string, string> columns, string templetePath, DataTable data)
            {
                using (FileStream fs = new FileStream(templetePath, FileMode.OpenOrCreate, FileAccess.ReadWrite))
                using (HSSFWorkbook workbook = new HSSFWorkbook(fs))
                using (HSSFSheet sheet1 = workbook.GetSheetAt(0) as HSSFSheet)
                using (MemoryStream stream = new MemoryStream())
                {
                    HSSFRow headerRow = sheet1.GetRow(0) as HSSFRow;//获取sheet的首行
                    int cellCount = headerRow.LastCellNum;  //一行最后一个方格的编号 即总的列数
                    int cellRowsCount = sheet1.LastRowNum + 1;//这个好像是获取的下标,所以加一。
    
                    if (cellCount != columns.Count)
                    {
                        throw new ArgumentException(nameof(columns));
                    }
                    if (cellRowsCount < 1)
                    {
                        throw new ArgumentNullException(nameof(cellRowsCount));
                    }
    
                    //赋值前清除下数据
                    for (int i = 1; i < cellRowsCount; i++) if (sheet1.GetRow(i) == null) continue; else sheet1.RemoveRow(sheet1.GetRow(i));
    
                    DocumentSummaryInformation dsi = PropertySetFactory.CreateDocumentSummaryInformation();//配置文件属性
                    dsi.Company = string.Empty;
                    dsi.Category = string.Empty;//类别
                    dsi.Manager = string.Empty;//管理者
                    workbook.DocumentSummaryInformation = dsi;
                    SummaryInformation si = PropertySetFactory.CreateSummaryInformation();
                    si.Subject = string.Empty;//主题
                    si.Title = string.Empty;//标题
                    si.ApplicationName = string.Empty;//不知道是啥
                    si.Author = string.Empty;//作者
                    si.LastAuthor = string.Empty;//上一次保存者
                    si.Comments = string.Empty;//备注
                    si.CreateDateTime = DateTime.Now;
                    workbook.SummaryInformation = si;
    
                    DataRow[] dataRows = data.AsEnumerable().ToArray();
                    string[] columnNames = columns.Keys.ToArray();
    
                    //数据库中的列名,按照Excel中的列顺序排列。
                    List<string> dbColumnNames = new List<string>();
                    var columnRow = sheet1.GetRow(0);
                    for (int i = 0; i < cellCount; i++)
                    {
                        var excelColumnName = columnRow.GetCell(i).ToString().Trim();
                        foreach (var colKey in columnNames)
                        {
                            if (string.Equals(columns[colKey], excelColumnName, StringComparison.OrdinalIgnoreCase))
                            {
                                dbColumnNames.Add(colKey);
                                break;
                            }
                        }
                    }
    
                    //转成数组使用,因为感觉这样后面使用快一点。
                    string[] dbColumnNamesArray = dbColumnNames.ToArray();
    
                    if (dbColumnNamesArray.Length != cellCount)
                    {
                        throw new ArgumentException(nameof(dbColumnNamesArray));
                    }
    
                    //单元格赋值
                    for (int i = 0, c = dataRows.Length; i < c; i++)
                    {
                        Row row1 = sheet1.CreateRow(i + 1);
                        for (int j = 0; j < cellCount; j++)
                        {
                            Cell cell = row1.CreateCell(j);
                            var value = dataRows[i][dbColumnNamesArray[j]];
                            if (value != null && value != DBNull.Value)
                            {
                                cell.SetCellValue(value.ToString());
                            }
                            else
                            {
                                cell.SetCellValue(string.Empty);
                            }
                        }
                    }
    
                    workbook.Write(stream);
                    return stream.ToArray();
                }
            }
    
    //使用
    var columns = new Dictionary<string, string>()
    {
      { "Name","名称" },
      { "Age","年龄" },
    };
    DataTable dt = GetDataTable();
    dt.TableName = "导出的Excel";
    DataTableToExcel(columns,Server.MapPath("~/template/test.xls"),dt);
    
            /// <summary>
            /// 获取excel单元格中的值
            /// </summary>
            /// <param name="cellObj"></param>
            /// <returns></returns>
            public static string GetExcelCellValue(Cell cellObj, NPOI.SS.UserModel.Workbook workbook)
            {
                if (cellObj == null) return string.Empty;
    
                string cellValue = null;
    
                switch (cellObj.CellType)
                {
                    case CellType.Unknown:
                        break;
                    case CellType.NUMERIC:
                        //NPOI中数字和日期都是NUMERIC类型的,这里对其进行判断是否是日期类型
                        if (DateUtil.IsCellDateFormatted(cellObj))//日期类型
                        {
                            var date = cellObj.DateCellValue;
                            if (date != default(DateTime) && date != DateTime.MinValue)
                            {
                                cellValue = date.ToString("yyyy/MM/dd HH:mm:ss");
                            }
                        }
                        else//其他数字类型
                        {
                            cellValue = cellObj.NumericCellValue.ToString();
                        }
                        break;
                    case CellType.STRING:
                        cellValue = cellObj.StringCellValue;
                        break;
                    case CellType.FORMULA:
                        var eva = new NPOI.HSSF.UserModel.HSSFFormulaEvaluator(workbook);
                        cellValue = eva.Evaluate(cellObj).StringValue;
                        break;
                    case CellType.BLANK:
                        break;
                    case CellType.BOOLEAN:
                        cellValue = cellObj.BooleanCellValue.ToString();
                        break;
                    case CellType.ERROR:
                        cellValue = cellObj.ErrorCellValue.ToString();
                        break;
                    default:
                        break;
                }
    
                cellValue = string.IsNullOrWhiteSpace(cellValue) ? string.Empty : cellValue.Trim();
    
                return cellValue;
            }
    
    
    /*下面的代码虽然是我写的,但是我不是很清楚啥作用了。而且是和业务以及asp的控件交织在一起的,所以这个也就记录下,不需要看懂。*/
    
            /// <summary>
            /// 上传Excel并且返回Excel中的数据
            /// </summary>
            /// <param name="columns">表列名和Excel中的列名字典</param>
            /// <param name="fuInvoiceFile">上传文件的控件</param>
            /// <returns>1:是否上传成功;2:上传成功后的数据;3:上传失败的错误消息;4:当前Excel的对象;5.文件上传后的地址</returns>
            protected Tuple<bool, DataTable, string, Workbook, string> GetExcelDataTable(Dictionary<string, string> columns, FileUpload fuInvoiceFile)
            {
                #region 文件校验、上传到服务器
    
                string fileName = fuInvoiceFile.ShortFileName.Replace(":", "_").Replace(" ", "_").Replace("\", "_").Replace("/", "_");
                if (fileName.LastIndexOf('.') <= 0)
                {
                    return new Tuple<bool, DataTable, string, Workbook, string>(false, null, "- 文件错误!", null, null);
                }
                string fileExt = fileName.Substring(fileName.LastIndexOf("."));
                // 文件验证
                if (fileExt != ".xls" && fileExt != ".xlsx")
                {
                    return new Tuple<bool, DataTable, string, Workbook, string>(false, null, "- 只能选择Excel文件导入!", null, null);
                }
                string onlyFileName = fileName.Substring(0, fileName.LastIndexOf(".") + 1);
                string dir = $@"{Server.MapPath(@"upfile")}{DateTime.Now:yyyy-MM-dd}";
                if (!Directory.Exists(dir)) Directory.CreateDirectory(dir);  // 创建日期目录
                string filePath = $"{dir}{onlyFileName}{Guid.NewGuid().ToString().Replace("-", string.Empty)}{fileExt}"; // 获得文件保存在服务器上的路径
    
                // 保存文件到服务器
                fuInvoiceFile.PostedFile.SaveAs(filePath);
    
                #endregion
    
                #region 实例化一个Excel
    
                FileStream fs = new FileStream(filePath, FileMode.Open);
                NPOI.SS.UserModel.Workbook workbook = new NPOI.HSSF.UserModel.HSSFWorkbook(fs);
                fs.Dispose();
                NPOI.SS.UserModel.Sheet sheet = workbook.GetSheetAt(0);
                if (sheet == null)
                {
                    sheet = workbook.CreateSheet("Sheet1");
                }
    
                #endregion
    
                #region 文件校验
    
                if (sheet.PhysicalNumberOfRows < 2)
                {
                    return new Tuple<bool, DataTable, string, Workbook, string>(false, null, "- 未获取到数据,请检查数据文件!", null, null);
                }
    
                var headerRow = sheet.GetRow(0) as NPOI.HSSF.UserModel.HSSFRow;//获取sheet的首行
                int cellCount = headerRow.LastCellNum;  //一行最后一个方格的编号 即总的列数
                //int cellRowsCount = sheet.LastRowNum + 1;//这个好像是获取的下标,所以加一。
    
                if (cellCount != columns.Count)
                {
                    return new Tuple<bool, DataTable, string, Workbook, string>(false, null, "- 列数不正确,请检查Excel文件!", null, null);
                }
    
    
                DataTable dt = new DataTable();
                var columnsKeys = columns.Keys.ToArray();
                for (int j = 0, clos = columnsKeys.Length; j < clos; j++)
                {
                    var headerText = headerRow.GetCell(j).ToString();
    
                    bool isNotExits = true;
    
                    foreach (var headerKey in columnsKeys)
                    {
                        var columnName = columns[headerKey];
                        if (columnName == headerText)
                        {
                            dt.Columns.Add(headerKey, typeof(string));
                            isNotExits = false;
                            break;
                        }
                    }
    
                    if (isNotExits)
                    {
                        return new Tuple<bool, DataTable, string, Workbook, string>(false, null, $"- 列名称[{headerText}]无法匹配,请使用系统提供的Excel模版导入!", null, null);
                    }
                }
    
                #endregion
    
                #region 读取数据
    
                for (int i = 1, rows = sheet.PhysicalNumberOfRows; i < rows; i++)
                {
                    var dtRow = dt.NewRow();
                    for (int j = 0, clos = columnsKeys.Length; j < clos; j++)
                    {
                        Row excelRow = sheet.GetRow(i);
                        if (excelRow == null) excelRow = sheet.CreateRow(i);
                        Cell cellObj = excelRow.GetCell(j);
                        if (cellObj == null) cellObj = excelRow.CreateCell(j);
    
                        dtRow[j] = DataTableRenderToExcel.GetExcelCellValue(cellObj, workbook);
                    }
                    dt.Rows.Add(dtRow);
                }
    
    
                #endregion
    
                #region 数据处理
    
                /// <summary>
                /// 删除DataTable下方的空数据行
                /// </summary>
                /// <param name="dt">要删除下方空数据行的数据列表</param>
                /// <param name="startIndex">有效列开始下标</param>
                /// <param name="endIndex">有效列结束下标</param>
                void DeleteDataTableBelowNullData(DataTable dtd, int startIndex, int endIndex)
                {
                    if (dtd == null) return;
    
                    int colLength = endIndex - startIndex + 1;
    
                    for (int i = dtd.Rows.Count - 1; i >= 0; i--)
                    {
                        var row = dtd.Rows[i].ItemArray;
                        int j = 0;
                        for (int y = startIndex; y <= endIndex; y++)
                        {
                            if (string.IsNullOrWhiteSpace(row?[y]?.ToString()))
                            {
                                j++;
                            }
                            else
                            {
                                break;
                            }
                        }
                        if (j == colLength)
                        {
                            dtd.Rows.RemoveAt(i);
                        }
                        else
                        {
                            break;
                        }
                    }
                }
    
                DeleteDataTableBelowNullData(dt, 1, dt.Columns.Count - 1);
    
                #endregion
    
                return new Tuple<bool, DataTable, string, Workbook, string>(true, dt, null, workbook, filePath);
            }
    
            /// <summary>
            /// 执行Excel导入错误校验
            /// </summary>
            /// <param name="workbook">需要写入的Excel对象</param>
            /// <param name="messages">错误消息集合</param>
            /// <param name="filePath">Excel文件地址</param>
            /// <returns></returns>
            protected Tuple<bool, string> ExeExcelErrorMessage(Workbook workbook, List<string> messages, string filePath)
            {
                var sheet = workbook.GetSheetAt(0);
    
                Row excelRowHead = sheet.GetRow(0);
    
                int errorColIndex = excelRowHead.LastCellNum + 1;
    
                if (excelRowHead == null) excelRowHead = sheet.CreateRow(0);
                Cell excelCellErrorTipHead = excelRowHead.GetCell(errorColIndex);
                if (excelCellErrorTipHead == null) excelCellErrorTipHead = excelRowHead.CreateCell(errorColIndex);
                excelCellErrorTipHead.SetCellValue("导入提示");
    
                bool hasError = false;
    
                for (int i = 0, count = messages.Count; i < count; i++)
                {
                    string errorMessage = messages[i];
                    Row excelRow = sheet.GetRow(i + 1);
                    if (errorMessage.Length > 0)
                    {
                        Cell cell = excelRow.GetCell(errorColIndex);
                        if (cell == null) cell = excelRow.CreateCell(errorColIndex);
                        cell.SetCellValue(errorMessage);
                        hasError = true;
                    }
                }
    
                string navigateUrl = null;
    
                if (hasError)
                {
                    navigateUrl = string.Format("~/upfile/{0}/{1}", DateTime.Now.ToString("yyyy-MM-dd"), filePath.Substring(filePath.LastIndexOf('\') + 1));
    
                    var fs = new FileStream(Server.MapPath(navigateUrl), FileMode.OpenOrCreate, FileAccess.ReadWrite);
                    workbook.Write(fs);
                    fs.Dispose();
    
                }
                else
                {
                    if (File.Exists(filePath)) File.Delete(filePath);
                }
                workbook.Dispose();
    
                return new Tuple<bool, string>(hasError, navigateUrl);
            }
    
  • 相关阅读:
    三次请求(读-改-读)引出nibernate 一级缓存
    算法竞赛入门经典第一、二章摘记
    uva 10905 Children's Game
    uva 11205 The broken pedometer
    uva 10160 Servicing stations
    uva 208 Firetruck
    uva 167 The Sultan's Successors
    zoj 1016 Parencodings
    uva 307 Sticks
    uva 216 Getting in Line
  • 原文地址:https://www.cnblogs.com/cluyun/p/14752228.html
Copyright © 2011-2022 走看看