C# 使用NPOI手搓excel转html

/// <summary>
/// excel转html
/// </summary>
public class ExcelToHtml
{
    /// <summary>
    /// excel转html
    /// </summary>
    /// <param name="inputFilePath"></param>
    /// <param name="outputHtmlPath"></param>
    public static void ConvertExcelToHtml(string inputFilePath, string outputHtmlPath)
    {
        // 创建一个HSSFWorkbook对象来处理.xls文件,如果是.xlsx文件,则应使用XSSFWorkbook
        using (var file = new FileStream(inputFilePath, FileMode.Open, FileAccess.Read))
        {
            IWorkbook workbook = null;
            try
            {
                //获取后缀名称
                string fileExt = AlphaFS.Path.GetExtension(inputFilePath)?.ToLower();
                switch (fileExt)
                {
                    //如果是XLSX格式选择XSSFWorkbook ,如果是XLS格式选择HSSFWorkbook 
                    case ".xlsx":
                        workbook = new XSSFWorkbook(file);
                        break;
                    case ".xls":
                        workbook = new HSSFWorkbook(file);
                        break;
                }
                StringBuilder htmlBuilder = new StringBuilder();
                //获取文件名称作为标题
                htmlBuilder.Append($"<html><head><title>{AlphaFS.Path.GetFileNameWithoutExtension(inputFilePath)}</title><meta http-equiv=\"content-type\" content=\"text/html;charset=utf-8\"></head><style>\r\n.excel-table {{\r\n        border-collapse: collapse;\r\n    }}\r\n\r\n    .excel-table tr:nth-child(odd) {{\r\n        border-bottom: 1px solid #ccc;\r\n    }}\r\n\r\n    .excel-table th, .excel-table td {{\r\n        border: 1px solid #ccc;\r\n        padding: 5px;\r\n    }}\r\n</style><body>");
                for (int sheetIndex = 0; sheetIndex < workbook.NumberOfSheets; sheetIndex++)
                {
                    ISheet sheet = workbook.GetSheetAt(sheetIndex);
                    if (sheet == null) continue;
                    List<CellRangeAddress> mergedRegions = sheet.MergedRegions;
                    htmlBuilder.AppendFormat("<div style=\"text-align: center;\"><h1>{0}</h1></div>", sheet.SheetName);
                    htmlBuilder.Append("<table class=\"excel-table\">");
                    HashSet<string> rows = new HashSet<string>();
                    HashSet<string> cells = new HashSet<string>();
                    // 遍历行
                    for (int rowNum = sheet.FirstRowNum; rowNum <= sheet.LastRowNum; rowNum++)
                    {
                        IRow row = sheet.GetRow(rowNum);
                        if (row == null) continue;
                        if (row.ZeroHeight) { continue; }
                        bool isBlankRow = true;
                        for (int colIdx = row.FirstCellNum; colIdx < row.LastCellNum; colIdx++)
                        {
                            ICell cell = row.GetCell(colIdx, MissingCellPolicy.RETURN_BLANK_AS_NULL);
                            if (cell != null && !string.IsNullOrEmpty(cell.ToString()))
                            {
                                isBlankRow = false;
                                break;
                            }
                        }
                        if (isBlankRow) continue;
                        htmlBuilder.Append("<tr>");
                        int mergedRows = 0; // 合并行数,默认为0
                        int mergedCols = 0; // 合并列数,默认为0
                        // 遍历单元格
                        for (int cellNum = row.FirstCellNum; cellNum <= row.LastCellNum; cellNum++)
                        {
                            ICell cell = row.GetCell(cellNum);
                            if (cell == null) continue;
                            bool isHidden = cell.CellStyle.IsHidden;
                            if (isHidden) { mergedCols++; continue; };
                            // 判断单元格是否属于合并区域
                            if (mergedCols == row.LastCellNum) break; // 合并列数等于行的最后一列时,跳出循环
                            if (cells.Contains(rowNum + "-" + cellNum)) { cells.Remove(rowNum + "-" + cellNum); continue; }// 合并列数大于当前列时,跳过当前列
                            if (rows.Contains(rowNum + "-" + cellNum))
                            {
                                mergedCols++;
                                //删除rows中的数据,以免影响下次循环时间
                                rows.Remove(rowNum + "-" + cellNum);
                                continue;
                            }  //如果已经合并过则跳过(防止重复合并)

                            if (!cell.IsMergedCell)
                            {
                                htmlBuilder.AppendFormat("<td ");
                                ProcessCellStyle(htmlBuilder, cell, workbook, sheet);
                                string cellValue = GetCellValue(cell, workbook);
                                htmlBuilder.AppendFormat(">{0}</td>", WebUtility.HtmlEncode(cellValue));
                                continue;

                            }
                            foreach (var region in mergedRegions)
                            {
                                if (!region.IsInRange(rowNum, cellNum)) continue;
                                //获取合并单元格的行数和列数
                                int rowspan = region.LastRow - region.FirstRow + 1;
                                int colspan = region.LastColumn - region.FirstColumn + 1;
                                mergedCols = colspan;
                                mergedRows = rowspan;
                                //mergedCols = colspan == row.LastCellNum ? colspan : mergedCols += colspan;
                                if (mergedCols > 1&& mergedCols!= row.LastCellNum && mergedRows==1)
                                {
                                    for (int i = 0; i < mergedCols; i++)
                                    {
                                        cells.Add(rowNum + "-" + (i + cellNum));
                                    }
                                }       
                                if (mergedRows > 1)
                                {
                                    for (int i = 0; i < mergedCols; i++)
                                    {
                                        for (int j = mergedRows + rowNum - 1; j > rowNum; j--)
                                        {
                                            rows.Add(j + "-" + (i + cellNum));
                                        }
                                    }
                                }
                                htmlBuilder.AppendFormat("<td ");
                                ProcessCellStyle(htmlBuilder, cell, workbook, sheet);
                                string cellValue = GetCellValue(cell, workbook);
                                htmlBuilder.AppendFormat(" rowspan='{0}' colspan='{1}'>{2}</td>", rowspan, colspan, cellValue);
                                break;
                            }
                        }

                        htmlBuilder.Append("</tr>");
                    }

                    htmlBuilder.Append("</table>");
                }
                htmlBuilder.Append("</body></html>");
                //判断路径是否存在
                if (!AlphaFS.Directory.Exists(AlphaFS.Path.GetDirectoryName(outputHtmlPath)))
                {
                    AlphaFS.Directory.CreateDirectory(AlphaFS.Path.GetDirectoryName(outputHtmlPath));
                }
                //判断文件是否存在,存在则覆盖
                if (AlphaFS.File.Exists(outputHtmlPath))
                {
                    AlphaFS.File.Delete(outputHtmlPath);
                }
                // 将生成的HTML写入文件
                AlphaFS.File.WriteAllText(outputHtmlPath, htmlBuilder.ToString());

            }
            catch (Exception ex)

            {
                Console.WriteLine(ex.Message);
            }
            finally
            {
                workbook?.Close();
            }
        }
    }

    private static void ProcessCellStyle(StringBuilder htmlBuilder, ICell cell, IWorkbook workbook, ISheet sheet)
    {
        if (cell == null) return;
        // 获取单元格的样式
        var cellStyle = cell.CellStyle;

        // 获取字体对象
        var font = cellStyle.GetFont(workbook);

        // 获取字体大小
        var fontSize = font.FontHeightInPoints;

        // 获取字体颜色
        var fontColor = font.Color;

        // 获取背景颜色
        var backgroundColor = cellStyle.FillForegroundColorColor;

        // 将样式转换为CSS格式
        string cssStyle = $"style=\"";

        cssStyle += $"font-size: {fontSize}px;";
        // 如果设置了字体颜色,则将其转为CSS格式
        if (fontColor != null)
        {
            string fontColorHex = "#" + fontColor.ToString("X6");
            cssStyle += $" color: {fontColorHex};";
        }

        // 如果设置了背景颜色,则将其转为CSS格式
        if (backgroundColor != null)
        {

            bool isXlsx = workbook is XSSFWorkbook;
            byte[] rgb = isXlsx ? ((NPOI.XSSF.UserModel.XSSFColor)cell.CellStyle.FillForegroundColorColor).RGB : ((NPOI.HSSF.Util.HSSFColor)cell.CellStyle.FillForegroundColorColor).RGB;
            string backgroundColorHex = "#" + BitConverter.ToString(rgb).Replace("-", string.Empty);
            cssStyle += $" background-color: {backgroundColorHex};";
        }
        // 边框
        //cssStyle += "border-style: " + cellStyle.BorderTop.ToString().ToLower() + ";";
        //cssStyle += "border-color: " + "#" + cellStyle.TopBorderColor.ToString("X6") + ";";


        // 获取单元格的宽度和高度
        IRow row = sheet.GetRow(cell.RowIndex);
        float cellWidth = sheet.GetColumnWidthInPixels(cell.ColumnIndex);
        float cellHeight = row.HeightInPoints / 0.75f;

        // 将宽度和高度转换为CSS单位(像素)
        string widthCss = "width: " + cellWidth.ToString() + "px;";
        string heightCss = "height: " + cellHeight.ToString() + "px;";
        cssStyle += widthCss + heightCss;
        cssStyle += "\"";
        htmlBuilder.Append(cssStyle);
        // 输出单元格的值和样式
        Console.WriteLine($" CSSStyle: {cssStyle}");

    }

    private static string GetCellValue(ICell cell, IWorkbook workbook)
    {
        switch (cell.CellType)
        {
            case CellType.Formula:
                // 计算公式结果
                workbook.GetCreationHelper().CreateFormulaEvaluator().EvaluateInCell(cell);
                return GetCellValue(cell, workbook);
            case CellType.Numeric:
                if (DateUtil.IsCellDateFormatted(cell))
                {
                    return cell.DateCellValue.ToString("yyyy-MM-dd"); // 格式化日期
                }
                else
                {
                    return cell.NumericCellValue.ToString(); // 数字格式
                }
            case CellType.String:
                return cell.StringCellValue;
            case CellType.Boolean:
                return cell.BooleanCellValue ? "True" : "False";
            default:
                return "";
        }
    }
}


excel效果:

image.png

html效果:

image.png




本文作者:admin

本文链接:https://www.javalc.com/post/114.html

版权声明:本篇文章于2024-01-29,由admin发表,转载请注明出处:分享你我。如有疑问,请联系我们

C# Json转换DataTable

发表评论

取消
扫码支持