diff --git a/src/main/java/com/example/exam/exam/service/wpsexcel/XlsxMaster.java b/src/main/java/com/example/exam/exam/service/wpsexcel/XlsxMaster.java index b151933..3ebcb25 100644 --- a/src/main/java/com/example/exam/exam/service/wpsexcel/XlsxMaster.java +++ b/src/main/java/com/example/exam/exam/service/wpsexcel/XlsxMaster.java @@ -207,7 +207,7 @@ public class XlsxMaster { if (value != null) { judgementXlsxVOS = setJudgementXlsx( judgementXlsxVOS, - docxFunction + "】@" + value, + docxFunction + "@" + value, firstName + examName + value ); } @@ -239,7 +239,7 @@ public class XlsxMaster { if (value != null) { judgementXlsxVOS = setJudgementXlsx( judgementXlsxVOS, - docxFunction + "】@" + value, + docxFunction + "@" + value, firstName + examName + value ); } @@ -262,7 +262,7 @@ public class XlsxMaster { if (value != null) { judgementXlsxVOS = setJudgementXlsx( judgementXlsxVOS, - docxFunction + "】@" + value, + docxFunction + "@" + value, firstName + examName + value ); } @@ -304,7 +304,7 @@ public class XlsxMaster { if (value != null) { judgementXlsxVOS = setJudgementXlsx( judgementXlsxVOS, - docxFunction + "】@" + value, + docxFunction + "@" + value, firstName + examName + value ); } @@ -350,7 +350,7 @@ public class XlsxMaster { if (value != null) { judgementXlsxVOS = setJudgementXlsx( judgementXlsxVOS, - docxFunction + "】@" + value, + docxFunction + "@" + value, firstName + examName + value ); } @@ -370,11 +370,16 @@ public class XlsxMaster { Method methodWithArgs = rangingFunctions.getClass().getMethod(function, paramTypes); int sheetNum = Integer.parseInt(number); - String value = (String) methodWithArgs.invoke(rangingFunctions,workbook,sheetNum-1); + String value = null; + try { + value = (String) methodWithArgs.invoke(rangingFunctions,workbook,sheetNum-1); + } catch (Exception e) { + e.printStackTrace(); + } if (value != null) { judgementXlsxVOS = setJudgementXlsx( judgementXlsxVOS, - docxFunction + "】@" + value, + docxFunction + "@" + value, firstName + examName + value ); } diff --git a/src/main/java/com/example/exam/exam/service/wpsexcel/cell/CellIng.java b/src/main/java/com/example/exam/exam/service/wpsexcel/cell/CellIng.java index 47c0f13..6823010 100644 --- a/src/main/java/com/example/exam/exam/service/wpsexcel/cell/CellIng.java +++ b/src/main/java/com/example/exam/exam/service/wpsexcel/cell/CellIng.java @@ -1,80 +1,85 @@ package com.example.exam.exam.service.wpsexcel.cell; import com.example.exam.exam.service.wpsword.docx4j.utils.ColorUtils; +import org.apache.poi.hssf.usermodel.HSSFCellStyle; import org.apache.poi.hssf.usermodel.HSSFFont; import org.apache.poi.hssf.usermodel.HSSFPalette; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.hssf.util.HSSFColor; import org.apache.poi.ss.usermodel.*; -import org.apache.poi.xssf.usermodel.XSSFCellStyle; -import org.apache.poi.xssf.usermodel.XSSFColor; -import org.apache.poi.xssf.usermodel.XSSFFont; +import org.apache.poi.ss.util.CellRangeAddress; +import org.apache.poi.xssf.usermodel.*; +import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTBorder; +import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTBorderPr; + +import java.lang.reflect.Method; public class CellIng { // 获取左框线样式 - public String getLeftBorderStyle(Cell cell, Workbook wb) { + public String getLeftBorderStyle(Cell cell, org.apache.poi.ss.usermodel.Workbook wb) { CellStyle style = cell.getCellStyle(); BorderStyle border = style.getBorderLeft(); return border != null ? border.name() : "无"; } // 获取左框线颜色 - public String getLeftBorderColor(Cell cell, Workbook wb) { + public String getLeftBorderColor(Cell cell, org.apache.poi.ss.usermodel.Workbook wb) { CellStyle style = cell.getCellStyle(); if (style instanceof XSSFCellStyle) { XSSFCellStyle xssfStyle = (XSSFCellStyle) style; - return getColorNameOrRGB(xssfStyle.getLeftBorderXSSFColor()); + + return ColorUtils.getChineseColorName(getColorNameOrRGB(xssfStyle.getLeftBorderXSSFColor())); } return "无"; } // 获取上框线样式 - public String getTopBorderStyle(Cell cell, Workbook wb) { + public String getTopBorderStyle(Cell cell, org.apache.poi.ss.usermodel.Workbook wb) { CellStyle style = cell.getCellStyle(); BorderStyle border = style.getBorderTop(); return border != null ? border.name() : "无"; } // 获取上框线颜色 - public String getTopBorderColor(Cell cell, Workbook wb) { + public String getTopBorderColor(Cell cell, org.apache.poi.ss.usermodel.Workbook wb) { CellStyle style = cell.getCellStyle(); if (style instanceof XSSFCellStyle) { XSSFCellStyle xssfStyle = (XSSFCellStyle) style; - return getColorNameOrRGB(xssfStyle.getTopBorderXSSFColor()); + return ColorUtils.getChineseColorName(getColorNameOrRGB(xssfStyle.getTopBorderXSSFColor())); } return "无"; } // 获取右框线样式 - public String getRightBorderStyle(Cell cell, Workbook wb) { + public String getRightBorderStyle(Cell cell, org.apache.poi.ss.usermodel.Workbook wb) { CellStyle style = cell.getCellStyle(); BorderStyle border = style.getBorderRight(); return border != null ? border.name() : "无"; } // 获取右框线颜色 - public String getRightBorderColor(Cell cell, Workbook wb) { + public String getRightBorderColor(Cell cell, org.apache.poi.ss.usermodel.Workbook wb) { CellStyle style = cell.getCellStyle(); if (style instanceof XSSFCellStyle) { XSSFCellStyle xssfStyle = (XSSFCellStyle) style; - return getColorNameOrRGB(xssfStyle.getRightBorderXSSFColor()); + return ColorUtils.getChineseColorName(getColorNameOrRGB(xssfStyle.getRightBorderXSSFColor())); } return "无"; } // 获取下框线样式 - public String getBottomBorderStyle(Cell cell, Workbook wb) { + public String getBottomBorderStyle(Cell cell, org.apache.poi.ss.usermodel.Workbook wb) { CellStyle style = cell.getCellStyle(); BorderStyle border = style.getBorderBottom(); return border != null ? border.name() : "无"; } // 获取下框线颜色 - public String getBottomBorderColor(Cell cell, Workbook wb) { + public String getBottomBorderColor(Cell cell, org.apache.poi.ss.usermodel.Workbook wb) { CellStyle style = cell.getCellStyle(); if (style instanceof XSSFCellStyle) { XSSFCellStyle xssfStyle = (XSSFCellStyle) style; - return getColorNameOrRGB(xssfStyle.getBottomBorderXSSFColor()); + return ColorUtils.getChineseColorName(getColorNameOrRGB(xssfStyle.getBottomBorderXSSFColor())); } return "无"; } @@ -217,6 +222,178 @@ public class CellIng { return "无"; } + // 删除线 + public static String getCellStrikeThrough(Cell cell, Workbook wb) { + if (cell == null) return "否"; + CellStyle style = cell.getCellStyle(); + if (style == null) return "否"; + return style.getFontIndexAsInt() >= 0 && wb.getFontAt(style.getFontIndexAsInt()).getStrikeout() + ? "是" : "否"; + } + + // 上标 + public static String getCellSuperScript(Cell cell, Workbook wb) { + if (cell == null) return "否"; + CellStyle style = cell.getCellStyle(); + if (style == null) return "否"; + short typeOffset = wb.getFontAt(style.getFontIndexAsInt()).getTypeOffset(); + return typeOffset == Font.SS_SUPER ? "是" : "否"; + } + + // 下标 + public static String getCellSubScript(Cell cell, Workbook wb) { + if (cell == null) return "否"; + CellStyle style = cell.getCellStyle(); + if (style == null) return "否"; + short typeOffset = wb.getFontAt(style.getFontIndexAsInt()).getTypeOffset(); + return typeOffset == Font.SS_SUB ? "是" : "否"; + } + + + + // 获取斜下框线样式 + public static String getDiagonalDownBorderStyle(Cell cell, Workbook wb) { + if (cell == null || !(cell instanceof XSSFCell)) return "无"; + XSSFCellStyle style = (XSSFCellStyle) cell.getCellStyle(); + + try { + // 通过反射获取私有方法 getCTBorder + Method method = XSSFCellStyle.class.getDeclaredMethod("getCTBorder"); + method.setAccessible(true); + CTBorder ctBorder = (CTBorder) method.invoke(style); + + if (ctBorder != null && ctBorder.isSetDiagonal()) { + // 判断斜线方向是否向下 + if (ctBorder.getDiagonalDown()) { + CTBorderPr borderPr = ctBorder.getDiagonal(); // 斜线的边框属性 + if (borderPr != null && borderPr.getStyle() != null) { + return borderPr.getStyle().toString(); + } + } + } + } catch (Exception e) { + e.printStackTrace(); + } + return "无"; + } + + // 斜下框线→颜色 + public static String getDiagonalDownBorderColor(Cell cell, Workbook wb) { + if (cell == null || !(cell instanceof XSSFCell)) return "无"; + XSSFCellStyle style = (XSSFCellStyle) cell.getCellStyle(); + + try { + Method method = XSSFCellStyle.class.getDeclaredMethod("getCTBorder"); + method.setAccessible(true); + CTBorder ctBorder = (CTBorder) method.invoke(style); + + if (ctBorder != null && ctBorder.isSetDiagonal() && ctBorder.getDiagonalDown()) { + CTBorderPr borderPr = ctBorder.getDiagonal(); + if (borderPr != null && borderPr.isSetColor()) { + String color = borderPr.getColor().getRgb().toString(); // 返回 RGB 字符串 + return color != null ? ColorUtils.getChineseColorName(color) : "无"; + } + } + } catch (Exception e) { + e.printStackTrace(); + } + return "无"; + } + + // 斜上框线→样式 + public static String getDiagonalUpBorderStyle(Cell cell, Workbook wb) { + if (cell == null || !(cell instanceof XSSFCell)) return "无"; + XSSFCellStyle style = (XSSFCellStyle) cell.getCellStyle(); + + try { + Method method = XSSFCellStyle.class.getDeclaredMethod("getCTBorder"); + method.setAccessible(true); + CTBorder ctBorder = (CTBorder) method.invoke(style); + + if (ctBorder != null && ctBorder.isSetDiagonal() && ctBorder.getDiagonalUp()) { + CTBorderPr borderPr = ctBorder.getDiagonal(); + if (borderPr != null && borderPr.getStyle() != null) { + return borderPr.getStyle().toString(); + } + } + } catch (Exception e) { + e.printStackTrace(); + } + return "无"; + } + + // 斜上框线→颜色 + public static String getDiagonalUpBorderColor(Cell cell, Workbook wb) { + if (cell == null || !(cell instanceof XSSFCell)) return "无"; + XSSFCellStyle style = (XSSFCellStyle) cell.getCellStyle(); + + try { + Method method = XSSFCellStyle.class.getDeclaredMethod("getCTBorder"); + method.setAccessible(true); + CTBorder ctBorder = (CTBorder) method.invoke(style); + + if (ctBorder != null && ctBorder.isSetDiagonal() && ctBorder.getDiagonalUp()) { + CTBorderPr borderPr = ctBorder.getDiagonal(); + if (borderPr != null && borderPr.isSetColor()) { + String color = borderPr.getColor().getRgb().toString(); + return color != null ? ColorUtils.getChineseColorName(color) : "无"; + } + } + } catch (Exception e) { + e.printStackTrace(); + } + return "无"; + } + + + + + + + + + + + + + + + + + // ===== 获取单元格文本(String) ===== + public String getCellText(Cell cell, Workbook wb) { + if (cell == null) return "无"; + DataFormatter formatter = new DataFormatter(); + return formatter.formatCellValue(cell); + } + + // ===== 获取单元格值 + public String getCellValue(Cell cell, Workbook wb) { + if (cell == null) return ""; + + switch (cell.getCellType()) { + case STRING: + return cell.getStringCellValue(); + case NUMERIC: + if (DateUtil.isCellDateFormatted(cell)) { + return cell.getDateCellValue().toString(); + } else { + return String.valueOf((long) cell.getNumericCellValue()); + } + case BOOLEAN: + return String.valueOf(cell.getBooleanCellValue()); + case FORMULA: + return cell.getCellFormula(); // 返回公式原文,例如 "A1+B1" + case BLANK: + case _NONE: + case ERROR: + default: + return ""; + } + } + + + @@ -228,7 +405,7 @@ public class CellIng { } // 工具方法:颜色转换为 RGB 代码 - private String getColorNameOrRGB(XSSFColor color) { + private String getColorNameOrRGB(org.apache.poi.xssf.usermodel.XSSFColor color) { if (color == null) { return "无"; } @@ -238,4 +415,121 @@ public class CellIng { } return String.format("%02X%02X%02X", rgb[0] & 0xFF, rgb[1] & 0xFF, rgb[2] & 0xFF); } + + // 数字格式 + public static String getCellDataFormat(Cell cell, Workbook wb) { + if (cell == null) return "无"; + CellStyle style = cell.getCellStyle(); + if (style == null) return "无"; + return style.getDataFormatString(); + } + + // 水平对齐 + public static String getCellHorizontalAlignment(Cell cell, Workbook wb) { + if (cell == null) return "无"; + CellStyle style = cell.getCellStyle(); + if (style == null) return "无"; + HorizontalAlignment alignment = style.getAlignment(); + return alignment != null ? alignment.name() : "无"; + } + + // 垂直对齐 + public static String getCellVerticalAlignment(Cell cell, Workbook wb) { + if (cell == null) return "无"; + CellStyle style = cell.getCellStyle(); + if (style == null) return "无"; + VerticalAlignment alignment = style.getVerticalAlignment(); + return alignment != null ? alignment.name() : "无"; + } + + // 缩进 + public static String getCellIndent(Cell cell, Workbook wb) { + if (cell == null) return "0"; + CellStyle style = cell.getCellStyle(); + if (style == null) return "0"; + return String.valueOf(style.getIndention()); + } + + // 自动换行 + public static String getCellWrapText(Cell cell, Workbook wb) { + if (cell == null) return "否"; + CellStyle style = cell.getCellStyle(); + if (style == null) return "否"; + return style.getWrapText() ? "是" : "否"; + } + + // 缩小字体填充(ShrinkToFit) + public static String getCellShrinkToFit(Cell cell, Workbook wb) { + if (cell == null) return "否"; + CellStyle style = cell.getCellStyle(); + if (style == null) return "否"; + return style.getShrinkToFit() ? "是" : "否"; + } + + // 合并单元格 + public static String getCellMerged(Cell cell, Workbook wb) { + if (cell == null || wb == null) return "否"; + Sheet sheet = cell.getSheet(); + if (sheet == null) return "否"; + + int row = cell.getRowIndex(); + int col = cell.getColumnIndex(); + + for (int i = 0; i < sheet.getNumMergedRegions(); i++) { + CellRangeAddress range = sheet.getMergedRegion(i); + if (range.isInRange(row, col)) { + return "是"; + } + } + return "否"; + } + + + // 文本方向(rotation) + public static String getCellTextRotation(Cell cell, Workbook wb) { + if (cell == null) return "0"; + CellStyle style = cell.getCellStyle(); + if (style == null) return "0"; + return String.valueOf(style.getRotation()); // 旋转角度 + } + + // 文本样式(加粗/斜体/下划线等) + public static String getCellFontStyle(Cell cell, Workbook wb) { + if (cell == null) return "无"; + CellStyle style = cell.getCellStyle(); + if (style == null) return "无"; + + Font font; + if (wb instanceof XSSFWorkbook) { + font = wb.getFontAt(style.getFontIndexAsInt()); + } else if (wb instanceof HSSFWorkbook) { + font = wb.getFontAt(style.getFontIndexAsInt()); + } else { + return "无"; + } + + StringBuilder sb = new StringBuilder(); + if (font.getBold()) sb.append("加粗 "); + if (font.getItalic()) sb.append("斜体 "); + if (font.getUnderline() != Font.U_NONE) sb.append("下划线 "); + if (sb.length() == 0) sb.append("常规"); + return sb.toString().trim(); + } + + // 高度(行高) + public static String getCellRowHeight(Cell cell, Workbook wb) { + if (cell == null || cell.getSheet() == null) return "默认"; + Row row = cell.getRow(); + if (row == null) return "默认"; + return String.valueOf(row.getHeight() / 20.0) + " pt"; // row.getHeight() 单位为 twips (1/20 pt) + } + + // 宽度(列宽) + public static String getCellColumnWidth(Cell cell, Workbook wb) { + if (cell == null || cell.getSheet() == null) return "默认"; + int colWidth = cell.getSheet().getColumnWidth(cell.getColumnIndex()); // 单位 1/256字符 + return String.format("%.2f pt", colWidth / 256.0 * 7); // 约 7pt/字符宽,可根据字体调整 + } + + } diff --git a/src/main/java/com/example/exam/exam/service/wpsexcel/chart/ChartHandler.java b/src/main/java/com/example/exam/exam/service/wpsexcel/chart/ChartHandler.java index 9e569a4..35ca0b2 100644 --- a/src/main/java/com/example/exam/exam/service/wpsexcel/chart/ChartHandler.java +++ b/src/main/java/com/example/exam/exam/service/wpsexcel/chart/ChartHandler.java @@ -3,6 +3,7 @@ package com.example.exam.exam.service.wpsexcel.chart; import org.apache.poi.openxml4j.opc.PackagePart; import org.apache.poi.ss.usermodel.ClientAnchor; import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.util.CellReference; import org.apache.poi.xddf.usermodel.chart.XDDFCategoryDataSource; import org.apache.poi.xddf.usermodel.chart.XDDFChartData; @@ -13,10 +14,24 @@ import org.openxmlformats.schemas.drawingml.x2006.chart.*; import org.openxmlformats.schemas.drawingml.x2006.main.CTGraphicalObjectData; import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTGraphicalObjectFrame; import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTTwoCellAnchor; +import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTPivotTableDefinition; +import org.w3c.dom.Document; +import org.w3c.dom.NodeList; +import javax.xml.XMLConstants; +import javax.xml.namespace.NamespaceContext; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathFactory; +import java.io.IOException; import java.io.InputStream; +import java.lang.reflect.Method; import java.nio.charset.StandardCharsets; +import java.util.Iterator; import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; public class ChartHandler { @@ -30,23 +45,92 @@ public class ChartHandler { if (chart == null) return "无图表"; CTChart ctChart = chart.getCTChart(); - if (ctChart == null) return "无图表定义"; + if (ctChart == null || ctChart.getPlotArea() == null) return "无图表定义"; - // 这里尝试获取第一种图表类型 - if (ctChart.getPlotArea() != null) { - if (ctChart.getPlotArea().getBarChartList().size() > 0) return "条形图"; - if (ctChart.getPlotArea().getLineChartList().size() > 0) return "折线图"; - if (ctChart.getPlotArea().getPieChartList().size() > 0) return "饼图"; - if (ctChart.getPlotArea().getAreaChartList().size() > 0) return "面积图"; - if (ctChart.getPlotArea().getScatterChartList().size() > 0) return "散点图"; - // 可根据需求继续扩展 + CTPlotArea plotArea = ctChart.getPlotArea(); + + // ===== 柱形 / 条形图 ===== + if (!plotArea.getBarChartList().isEmpty()) { + CTBarChart barChart = plotArea.getBarChartArray(0); + STBarDir.Enum dir = barChart.getBarDir().getVal(); + STBarGrouping.Enum grouping = barChart.getGrouping().getVal(); + + String baseName = (dir == STBarDir.COL) ? "柱形图" : + (dir == STBarDir.BAR) ? "条形图" : "柱形/条形图"; + + if (grouping == STBarGrouping.CLUSTERED) { + return "簇状" + baseName; + } else if (grouping == STBarGrouping.STACKED) { + return "堆积" + baseName; + } else if (grouping == STBarGrouping.PERCENT_STACKED) { + return "百分比堆积" + baseName; + } else { + return baseName; + } } + if (!plotArea.getBar3DChartList().isEmpty()) { + return "三维柱形/条形图"; + } + + // ===== 折线图 ===== + if (!plotArea.getLineChartList().isEmpty()) { + return "折线图"; + } + if (!plotArea.getLine3DChartList().isEmpty()) { + return "三维折线图"; + } + + // ===== 饼图 ===== + if (!plotArea.getPieChartList().isEmpty()) { + return "饼图"; + } + if (!plotArea.getPie3DChartList().isEmpty()) { + return "三维饼图"; + } + + // ===== 面积图 ===== + if (!plotArea.getAreaChartList().isEmpty()) { + return "面积图"; + } + if (!plotArea.getArea3DChartList().isEmpty()) { + return "三维面积图"; + } + + // ===== 散点图 ===== + if (!plotArea.getScatterChartList().isEmpty()) { + return "散点图"; + } + + // ===== 雷达图 ===== + if (!plotArea.getRadarChartList().isEmpty()) { + return "雷达图"; + } + + // ===== 气泡图 ===== + if (!plotArea.getBubbleChartList().isEmpty()) { + return "气泡图"; + } + + // ===== 组合图(多个 chart 类型) ===== + int chartTypeCount = 0; + if (!plotArea.getBarChartList().isEmpty() || !plotArea.getBar3DChartList().isEmpty()) chartTypeCount++; + if (!plotArea.getLineChartList().isEmpty() || !plotArea.getLine3DChartList().isEmpty()) chartTypeCount++; + if (!plotArea.getPieChartList().isEmpty() || !plotArea.getPie3DChartList().isEmpty()) chartTypeCount++; + if (!plotArea.getAreaChartList().isEmpty() || !plotArea.getArea3DChartList().isEmpty()) chartTypeCount++; + if (!plotArea.getScatterChartList().isEmpty()) chartTypeCount++; + if (!plotArea.getRadarChartList().isEmpty()) chartTypeCount++; + if (!plotArea.getBubbleChartList().isEmpty()) chartTypeCount++; + + if (chartTypeCount > 1) return "组合图"; + return "未知图表类型"; } + + /** 图表-数据-数据系列 - 产生方式 */ public String getDataSeriesGeneration(XSSFChart chart, XSSFSheet sheet) { if (chart == null) return "无图表"; diff --git a/src/main/java/com/example/exam/exam/service/wpsexcel/range/RangIng.java b/src/main/java/com/example/exam/exam/service/wpsexcel/range/RangIng.java index dcb742d..0954478 100644 --- a/src/main/java/com/example/exam/exam/service/wpsexcel/range/RangIng.java +++ b/src/main/java/com/example/exam/exam/service/wpsexcel/range/RangIng.java @@ -74,7 +74,7 @@ public class RangIng { public String getFontName(String cellRef, Workbook workbook, int sheetIndex) { List cellRefs = getCellRefsInRange(cellRef); - String cellref= cellRefs.get(0); + String cellref= cellRefs.get(0); Cell cell = getPoiCellFromRef(workbook, sheetIndex-1, cellref); if (cell == null) return null; @@ -178,39 +178,58 @@ public class RangIng { CellStyle style = cell.getCellStyle(); short dataFormatIndex = style.getDataFormat(); String dataFormatString = style.getDataFormatString(); - System.out.println("数字格式索引: " + dataFormatIndex + ", 格式: " + dataFormatString); - return dataFormatString; + if(dataFormatString!=null){ + return dataFormatString; + } + return "无"; + } - //格式-合并单元格 (返回是否) + // 只有当 cellRefs 所有单元格都在同一个合并区域里时,才返回 "是" public String isMergedRegion(String cellRef, Workbook workbook, int sheetIndex) { List cellRefs = getCellRefsInRange(cellRef); - String cellref = cellRefs.get(0); - CellReference cr = new CellReference(cellref); - int rowIndex = cr.getRow(); - int colIndex = cr.getCol(); + if (cellRefs == null || cellRefs.isEmpty()) return "否"; Sheet sheet = workbook.getSheetAt(sheetIndex - 1); if (sheet == null) return "否"; int mergedRegionsCount = sheet.getNumMergedRegions(); + if (mergedRegionsCount == 0) return "否"; + + // 第一个单元格所在的合并区域 + CellReference firstCr = new CellReference(cellRefs.get(0)); + CellRangeAddress targetRange = null; for (int i = 0; i < mergedRegionsCount; i++) { CellRangeAddress range = sheet.getMergedRegion(i); - if (range.isInRange(rowIndex, colIndex)) { - return "是"; + if (range.isInRange(firstCr.getRow(), firstCr.getCol())) { + targetRange = range; + break; } } - return "否"; + + // 如果第一个单元格不在任何合并区域,直接否 + if (targetRange == null) return "否"; + + // 检查所有 cellRefs 是否都在同一个合并区域内 + for (String ref : cellRefs) { + CellReference cr = new CellReference(ref); + if (!targetRange.isInRange(cr.getRow(), cr.getCol())) { + return "否"; + } + } + + return "是"; } + //条件格式 - //格式 - //填充颜色 + //格式 + //填充颜色 public String printCellFormats(String cellRef, Workbook workbook, int sheetIndex) { List cellRefs = getCellRefsInRange(cellRef); String cellref = cellRefs.get(0); @@ -235,19 +254,23 @@ public class RangIng { // ===== 填充颜色 ===== if (rule.getPatternFormatting() != null) { XSSFPatternFormatting pf = rule.getPatternFormatting(); - Color bgColor = pf.getFillBackgroundColorColor(); - XSSFColor xssfColor = (XSSFColor) bgColor; - byte[] argb = xssfColor.getARGB(); - if (argb != null) { - String hex = String.format("%02X%02X%02X", argb[1], argb[2], argb[3]); - return ColorUtils.getChineseColorName(hex); - } else { - return "无"; + XSSFColor xssfColor = pf.getFillBackgroundColorColor(); + if (xssfColor != null) { + byte[] argb = xssfColor.getARGB(); + if (argb != null && argb.length == 4) { + String hex = String.format("%02X%02X%02X", argb[1], argb[2], argb[3]); + String chineseColorName = ColorUtils.getChineseColorName(hex); + // 转成十进制 RGB + int r = argb[1] & 0xFF; + int g = argb[2] & 0xFF; + int b = argb[3] & 0xFF; + String rgb = String.format(chineseColorName+",RGB(%d,%d,%d)", r, g, b); + return rgb; + } } - - - + return "无"; } + } } } @@ -278,18 +301,22 @@ public class RangIng { // ===== 字体颜色 ===== if (rule.getFontFormatting() != null) { XSSFFontFormatting ff = rule.getFontFormatting(); - Color fontColor = ff.getFontColor(); - XSSFColor xssfColor = (XSSFColor) fontColor; - byte[] argb = xssfColor.getARGB(); - if (argb != null) { - String hex = String.format("%02X%02X%02X", argb[1], argb[2], argb[3]); - return ColorUtils.getChineseColorName(hex); - } else { - return "无"; + XSSFColor xssfColor = ff.getFontColor(); + if (xssfColor != null) { + byte[] argb = xssfColor.getARGB(); + if (argb != null && argb.length == 4) { + String hex = String.format("%02X%02X%02X", argb[1], argb[2], argb[3]); + String chineseColorName = ColorUtils.getChineseColorName(hex); + int r = argb[1] & 0xFF; + int g = argb[2] & 0xFF; + int b = argb[3] & 0xFF; + String rgb = String.format(chineseColorName+",RGB(%d,%d,%d)", r, g, b); + return rgb; + } } - - + return "无"; } + } } } @@ -320,7 +347,16 @@ public class RangIng { System.out.println("下边框颜色: " + (borderColorBottom != null ? borderColorBottom.getARGBHex() : "无")); System.out.println("左边框颜色: " + (borderColorLeft != null ? borderColorLeft.getARGBHex() : "无")); System.out.println("右边框颜色: " + (borderColorRight != null ? borderColorRight.getARGBHex() : "无")); - return ColorUtils.getChineseColorName(borderColorTop.getARGBHex() ); + if (borderColorTop != null && borderColorTop.getARGBHex() != null) { + String hex=borderColorTop.getARGBHex(); + if (hex != null && hex.length() == 8) { + hex = hex.substring(2); // 去掉前两位 Alpha + } + if (hex != null) { + return ColorUtils.getChineseColorName(hex); + } + } + return "无"; } else { System.out.println("边框颜色索引(旧版HSSF): top=" + style.getTopBorderColor() @@ -406,7 +442,13 @@ public class RangIng { XSSFCellStyle xssfStyle = (XSSFCellStyle) style; XSSFColor fillColor = xssfStyle.getFillForegroundXSSFColor(); if (fillColor != null && fillColor.getARGBHex() != null) { - return ColorUtils.getChineseColorName(fillColor.getARGBHex() ); + String hex=fillColor.getARGBHex(); + if (hex != null && hex.length() == 8) { + hex = hex.substring(2); // 去掉前两位 Alpha + } + if (hex != null) { + return ColorUtils.getChineseColorName(hex); + } } } } @@ -440,7 +482,7 @@ public class RangIng { Sheet sheet = workbook.getSheetAt(sheetIndex); if (sheet == null) return null; - CellReference ref = new CellReference(cellRef); + org.apache.poi.ss.util.CellReference ref = new org.apache.poi.ss.util.CellReference(cellRef); Row row = sheet.getRow(ref.getRow()); if (row == null) return null; diff --git a/src/main/java/com/example/exam/exam/service/wpsexcel/style/Style.java b/src/main/java/com/example/exam/exam/service/wpsexcel/style/Style.java index 2c7f2f7..11480e2 100644 --- a/src/main/java/com/example/exam/exam/service/wpsexcel/style/Style.java +++ b/src/main/java/com/example/exam/exam/service/wpsexcel/style/Style.java @@ -1,5 +1,6 @@ package com.example.exam.exam.service.wpsexcel.style; +import com.example.exam.exam.service.wpsword.docx4j.utils.ColorUtils; import org.apache.poi.ss.usermodel.*; import org.apache.poi.ss.util.CellReference; import org.apache.poi.xssf.usermodel.*; @@ -32,7 +33,13 @@ public class Style { Sheet sheet = workbook.getSheetAt(sheetNum); if (sheet instanceof XSSFSheet) { XSSFColor color = ((XSSFSheet) sheet).getTabColor(); - if (color != null) return color.getARGBHex(); + String hex=color.getARGBHex(); + if (hex != null && hex.length() == 8) { + hex = hex.substring(2); // 去掉前两位 Alpha + } + if (hex != null) { + return ColorUtils.getChineseColorName(hex); + } } return "无"; } diff --git a/src/main/java/com/example/exam/exam/service/wpsword/docx4j/paragraph/RunText.java b/src/main/java/com/example/exam/exam/service/wpsword/docx4j/paragraph/RunText.java index 745df03..3c72ce5 100644 --- a/src/main/java/com/example/exam/exam/service/wpsword/docx4j/paragraph/RunText.java +++ b/src/main/java/com/example/exam/exam/service/wpsword/docx4j/paragraph/RunText.java @@ -307,6 +307,8 @@ public class RunText { if (run == null) continue; RPr rPr = run.getRPr(); if (rPr != null && rPr.getU() != null && rPr.getU().getColor() != null) { + System.out.println("============================================================"); + System.out.println(ColorUtils.getChineseColorName(rPr.getU().getColor())+"''''''''''''''''''''''''''''''''''''"); return ColorUtils.getChineseColorName(rPr.getU().getColor()); } } @@ -320,6 +322,8 @@ public class RunText { Style style = stylePart.getStyleById(styleId); if (style != null && style.getRPr() != null && style.getRPr().getU() != null && style.getRPr().getU().getColor() != null) { + System.out.println("============================================================"); + System.out.println(ColorUtils.getChineseColorName(style.getRPr().getU().getColor())); return ColorUtils.getChineseColorName(style.getRPr().getU().getColor()); } } catch (Exception e) { diff --git a/src/main/java/com/example/exam/exam/service/wpsword/docx4j/utils/ColorUtils.java b/src/main/java/com/example/exam/exam/service/wpsword/docx4j/utils/ColorUtils.java index 8999344..fb0cc82 100644 --- a/src/main/java/com/example/exam/exam/service/wpsword/docx4j/utils/ColorUtils.java +++ b/src/main/java/com/example/exam/exam/service/wpsword/docx4j/utils/ColorUtils.java @@ -37,6 +37,7 @@ public class ColorUtils { COLOR_MAP.put("006600", "深绿色"); COLOR_MAP.put("99cc99", "浅绿色"); COLOR_MAP.put("00b0f0", "浅蓝色"); + COLOR_MAP.put("0070c0", "蓝色"); // 16进制颜色代码映射(统一小写) @@ -60,6 +61,7 @@ public class ColorUtils { COLOR_MAP.put("ffd700", "金色"); COLOR_MAP.put("e54c5e", "金色"); COLOR_MAP.put("00b050", "绿色"); + COLOR_MAP.put("ffc000", "橙色");