|
@@ -0,0 +1,460 @@
|
|
|
|
+package com.nokia.common.excel.poi;
|
|
|
|
+
|
|
|
|
+import java.awt.BasicStroke;
|
|
|
|
+import java.awt.Graphics2D;
|
|
|
|
+import java.awt.RenderingHints;
|
|
|
|
+import java.awt.image.BufferedImage;
|
|
|
|
+import java.text.DateFormat;
|
|
|
|
+import java.text.DecimalFormat;
|
|
|
|
+import java.text.SimpleDateFormat;
|
|
|
|
+import java.util.ArrayList;
|
|
|
|
+import java.util.HashMap;
|
|
|
|
+import java.util.List;
|
|
|
|
+import java.util.Map;
|
|
|
|
+
|
|
|
|
+import org.apache.poi.hssf.usermodel.HSSFFont;
|
|
|
|
+import org.apache.poi.hssf.usermodel.HSSFFormulaEvaluator;
|
|
|
|
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
|
|
|
+import org.apache.poi.hssf.util.HSSFColor;
|
|
|
|
+import org.apache.poi.ss.usermodel.Font;
|
|
|
|
+import org.apache.poi.ss.usermodel.BorderStyle;
|
|
|
|
+import org.apache.poi.ss.usermodel.Cell;
|
|
|
|
+import org.apache.poi.ss.usermodel.CellStyle;
|
|
|
|
+import org.apache.poi.ss.usermodel.CellValue;
|
|
|
|
+import org.apache.poi.ss.usermodel.Color;
|
|
|
|
+import org.apache.poi.ss.usermodel.ColorScaleFormatting;
|
|
|
|
+import org.apache.poi.ss.usermodel.ConditionalFormatting;
|
|
|
|
+import org.apache.poi.ss.usermodel.DateUtil;
|
|
|
|
+import org.apache.poi.ss.usermodel.FormulaEvaluator;
|
|
|
|
+import org.apache.poi.ss.usermodel.Row;
|
|
|
|
+import org.apache.poi.ss.usermodel.Sheet;
|
|
|
|
+import org.apache.poi.ss.usermodel.SheetConditionalFormatting;
|
|
|
|
+import org.apache.poi.ss.usermodel.Workbook;
|
|
|
|
+import org.apache.poi.ss.util.CellRangeAddress;
|
|
|
|
+import org.apache.poi.xssf.usermodel.XSSFColor;
|
|
|
|
+import org.apache.poi.xssf.usermodel.XSSFFont;
|
|
|
|
+import org.apache.poi.xssf.usermodel.XSSFFormulaEvaluator;
|
|
|
|
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
|
|
|
+
|
|
|
|
+import com.nokia.common.excel.entity.CellInfo;
|
|
|
|
+import com.nokia.common.excel.entity.CellRect;
|
|
|
|
+import com.nokia.common.excel.entity.Gradient;
|
|
|
|
+import com.nokia.common.excel.entity.ThreeColorGradient;
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * POI的封装
|
|
|
|
+ */
|
|
|
|
+public class PoiUtil {
|
|
|
|
+
|
|
|
|
+ private static DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
|
|
|
+ private static ThreeColorGradient threeColorGradient;
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 截图rect指定的区域
|
|
|
|
+ *
|
|
|
|
+ * @param sheet
|
|
|
|
+ * @param rect
|
|
|
|
+ * @return
|
|
|
|
+ */
|
|
|
|
+ public static BufferedImage screenShot(Sheet sheet, String rect) {
|
|
|
|
+ return screenShot(sheet, CellRect.parse(rect));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 使用指定的字体截图
|
|
|
|
+ *
|
|
|
|
+ * @param sheet
|
|
|
|
+ * @param rect
|
|
|
|
+ * @param fontFamily
|
|
|
|
+ * @return
|
|
|
|
+ */
|
|
|
|
+ public static BufferedImage screenShot(Sheet sheet, String rect, String fontFamily) {
|
|
|
|
+ CellRect cellRect = CellRect.parse(rect);
|
|
|
|
+ cellRect.setFontFamily(fontFamily);
|
|
|
|
+ return screenShot(sheet, cellRect);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 截取由startCol、endCol、startRow、endRow指定的Sheet中矩形区域所包含的单元格到BufferedImage
|
|
|
|
+ *
|
|
|
|
+ * @param sheet
|
|
|
|
+ * @param startCol
|
|
|
|
+ * @param endCol
|
|
|
|
+ * @param startRow
|
|
|
|
+ * @param endRow
|
|
|
|
+ * @return
|
|
|
|
+ */
|
|
|
|
+ public static BufferedImage screenShot(Sheet sheet, int startCol, int endCol, int startRow, int endRow) {
|
|
|
|
+ CellRect cellRect = new CellRect();
|
|
|
|
+ cellRect.setStartCol(startCol);
|
|
|
|
+ cellRect.setEndCol(endCol);
|
|
|
|
+ cellRect.setStartRow(startRow);
|
|
|
|
+ cellRect.setEndRow(endRow);
|
|
|
|
+ return screenShot(sheet, cellRect);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 截取由CellRect实例指定的Sheet中矩形区域所包含的单元格到BufferedImage
|
|
|
|
+ *
|
|
|
|
+ * @param sheet
|
|
|
|
+ * @param cellRect
|
|
|
|
+ * @return java.awt.image.BufferedImage
|
|
|
|
+ */
|
|
|
|
+ public static BufferedImage screenShot(Sheet sheet, CellRect cellRect) {
|
|
|
|
+ // 从excel读取截图范围内的信息
|
|
|
|
+ readCellRect(sheet, cellRect);
|
|
|
|
+ int imageWidth = cellRect.getTotalWidth();
|
|
|
|
+ int imageHeight = cellRect.getTotalHeight();
|
|
|
|
+ // 创建image
|
|
|
|
+ BufferedImage image = new BufferedImage(imageWidth, imageHeight,
|
|
|
|
+ BufferedImage.TYPE_INT_ARGB);
|
|
|
|
+ Graphics2D g2d = image.createGraphics();
|
|
|
|
+ // 平滑字体
|
|
|
|
+ g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
|
|
|
+ // 图片背景色
|
|
|
|
+ g2d.setColor(cellRect.getBackgroundColor());
|
|
|
|
+ g2d.fillRect(0, 0, imageWidth, imageHeight);
|
|
|
|
+ // 遍历CellInfo,将单元格输出到图片
|
|
|
|
+ for (CellInfo cellInfo : cellRect.getCellInfos()) {
|
|
|
|
+ // 背景色
|
|
|
|
+ if (cellInfo.getBackgroundColor() != null) {
|
|
|
|
+ g2d.setColor(cellInfo.getBackgroundColor());
|
|
|
|
+ g2d.fillRect(cellInfo.getX(), cellInfo.getY(), cellInfo.getWidth(), cellInfo.getHeight());
|
|
|
|
+ }
|
|
|
|
+ // 边框
|
|
|
|
+ if (cellInfo.isBordered()) {
|
|
|
|
+ g2d.setColor(cellInfo.getBorderColor());
|
|
|
|
+ g2d.setStroke(new BasicStroke(cellInfo.getBorderWidth()));
|
|
|
|
+ g2d.drawRect(cellInfo.getX(), cellInfo.getY(), cellInfo.getWidth(), cellInfo.getHeight());
|
|
|
|
+ }
|
|
|
|
+ // 写入值
|
|
|
|
+ g2d.setColor(cellInfo.getTextColor());
|
|
|
|
+ java.awt.Font font = cellInfo.getFont();
|
|
|
|
+ String text = cellInfo.getText();
|
|
|
|
+ int stringWidth = g2d.getFontMetrics(font).stringWidth(text);
|
|
|
|
+ g2d.setFont(font);
|
|
|
|
+ g2d.drawString(text, cellInfo.getX() + (cellInfo.getWidth() - stringWidth) / 2,
|
|
|
|
+ cellInfo.getY() + (cellInfo.getHeight() - font.getSize()) / 2 + font.getSize());
|
|
|
|
+ }
|
|
|
|
+ g2d.dispose();
|
|
|
|
+ return image;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 读取sheet中由cellRect指定的矩形区域内容,更新cellRect对象
|
|
|
|
+ *
|
|
|
|
+ * @param sheet
|
|
|
|
+ * @param cellRect
|
|
|
|
+ */
|
|
|
|
+ public static void readCellRect(Sheet sheet, CellRect cellRect) {
|
|
|
|
+ List<CellInfo> cellInfos = new ArrayList<>();
|
|
|
|
+ cellRect.setCellInfos(cellInfos);
|
|
|
|
+ // 种树原理,树比树空多1, 0-34有35个树空,需要种36棵树
|
|
|
|
+ int[] colPixPos = new int[cellRect.getEndCol() - cellRect.getStartCol() + 2];
|
|
|
|
+ int[] rowPixPos = new int[cellRect.getEndRow() - cellRect.getStartRow() + 2];
|
|
|
|
+ colPixPos[0] = cellRect.getMargin();
|
|
|
|
+ rowPixPos[0] = cellRect.getMargin();
|
|
|
|
+ for (int i = cellRect.getStartCol(); i <= cellRect.getEndCol(); i++) {
|
|
|
|
+ colPixPos[i + 1 - cellRect.getStartCol()] = (int) sheet.getColumnWidthInPixels(i) * 115 / 100
|
|
|
|
+ + colPixPos[i - cellRect.getStartCol()];
|
|
|
|
+ }
|
|
|
|
+ Row row;
|
|
|
|
+ Cell cell;
|
|
|
|
+ CellStyle cellStyle;
|
|
|
|
+ // 获取sheet中的合并单元格
|
|
|
|
+ List<CellRangeAddress> mergedRegions = sheet.getMergedRegions();
|
|
|
|
+ // 获取sheet中的条件背景色
|
|
|
|
+ Map<String, ThreeColorGradient> conditionalBackgroundColor = getConditionalBackgroundColor(sheet);
|
|
|
|
+ for (int i = cellRect.getStartRow(); i <= cellRect.getEndRow(); i++) {
|
|
|
|
+ row = sheet.getRow(i);
|
|
|
|
+ if (row == null) {
|
|
|
|
+ throw new RuntimeException(String.format("readCellRectd调用出错, Row-%s 为空", i));
|
|
|
|
+ }
|
|
|
|
+ rowPixPos[i + 1 - cellRect.getStartRow()] = (int) row.getHeightInPoints() * 96 / 72
|
|
|
|
+ + rowPixPos[i - cellRect.getStartRow()];
|
|
|
|
+ for (int j = cellRect.getStartCol(); j <= cellRect.getEndCol(); j++) {
|
|
|
|
+ // 行号i 列号j
|
|
|
|
+ // 判断是否为合并单元格
|
|
|
|
+ int[] inMerged = isInMerged(i, j, mergedRegions);
|
|
|
|
+ if (inMerged[0] == 0 && inMerged[1] == 0) {
|
|
|
|
+ // 是合并单元格且不是第一个单元格,可以忽略,跳过单元格
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ cell = row.getCell(j);
|
|
|
|
+ // 其他情况都不能忽略
|
|
|
|
+ CellInfo cellInfo = new CellInfo();
|
|
|
|
+ cellInfos.add(cellInfo);
|
|
|
|
+ // 截图的时候应该按照原格式显示,比如保留的小数位
|
|
|
|
+ cellInfo.setText(readCellValueAsString(cell));
|
|
|
|
+ // 判断单元格是否包含条件背景色
|
|
|
|
+ threeColorGradient = conditionalBackgroundColor.get(i + "-" + j);
|
|
|
|
+ if (threeColorGradient != null) {
|
|
|
|
+ cellInfo.setBackgroundColor(threeColorGradient.getColor(row.getCell(j).getNumericCellValue()));
|
|
|
|
+ }
|
|
|
|
+ // 检查背景色
|
|
|
|
+ cellStyle = cell.getCellStyle();
|
|
|
|
+ // excel填充一般都是前景色
|
|
|
|
+ Color fillForegroundColorColor = cellStyle.getFillForegroundColorColor();
|
|
|
|
+ if (fillForegroundColorColor != null) {
|
|
|
|
+ cellInfo.setBackgroundColor(colorCodec(fillForegroundColorColor));
|
|
|
|
+ }
|
|
|
|
+ // 是否有边框,只检查左边框,只要不是NONE,截图就设置为全边框
|
|
|
|
+ if (cellStyle.getBorderLeft().equals(BorderStyle.NONE)) {
|
|
|
|
+ cellInfo.setBordered(false);
|
|
|
|
+ }
|
|
|
|
+ // 字体相关
|
|
|
|
+ Font fontAt = sheet.getWorkbook().getFontAt(cellStyle.getFontIndex());
|
|
|
|
+ // 字体颜色
|
|
|
|
+ cellInfo.setTextColor(fontColorCodec(fontAt, sheet.getWorkbook()));
|
|
|
|
+ StringBuffer stringBuffer = new StringBuffer();
|
|
|
|
+ // fontfamily
|
|
|
|
+ if (cellRect.getFontFamily() != null) {
|
|
|
|
+ stringBuffer.append(cellRect.getFontFamily());
|
|
|
|
+ } else {
|
|
|
|
+ stringBuffer.append(fontAt.getFontName());
|
|
|
|
+ }
|
|
|
|
+ // 加粗还是正常
|
|
|
|
+ if (fontAt.getBold()) {
|
|
|
|
+ stringBuffer.append("-BOLD-");
|
|
|
|
+ } else {
|
|
|
|
+ stringBuffer.append("-PLAIN-");
|
|
|
|
+ }
|
|
|
|
+ // 字体大小
|
|
|
|
+ int fontSize = fontAt.getFontHeightInPoints();
|
|
|
|
+ if (fontSize < cellRect.getFontSizeMin()) {
|
|
|
|
+ stringBuffer.append(cellRect.getFontSizeMin());
|
|
|
|
+ } else {
|
|
|
|
+ stringBuffer.append(fontSize);
|
|
|
|
+ }
|
|
|
|
+ cellInfo.setFont(stringBuffer.toString());
|
|
|
|
+ // 坐标
|
|
|
|
+ cellInfo.setX(colPixPos[j - cellRect.getStartCol()]);
|
|
|
|
+ cellInfo.setY(rowPixPos[i - cellRect.getStartRow()]);
|
|
|
|
+ // 计算单元格宽度和高度
|
|
|
|
+ cellInfo.setWidth(colPixPos[j + 1 - cellRect.getStartCol()] - colPixPos[j - cellRect.getStartCol()]);
|
|
|
|
+ cellInfo.setHeight(rowPixPos[i + 1 - cellRect.getStartRow()] - rowPixPos[i - cellRect.getStartRow()]);
|
|
|
|
+ // 合并单元格需要重新计算宽度和高度
|
|
|
|
+ if (inMerged[0] != -1 && inMerged[1] != -1) {
|
|
|
|
+ cellInfo.setWidth(colPixPos[inMerged[1] + 1 - cellRect.getStartCol()]
|
|
|
|
+ - colPixPos[j - cellRect.getStartCol()]);
|
|
|
|
+ cellInfo.setHeight(rowPixPos[inMerged[0] + 1 - cellRect.getStartRow()]
|
|
|
|
+ - rowPixPos[i - cellRect.getStartRow()]);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ cellRect.setTotalWidth(colPixPos[colPixPos.length - 1] + cellRect.getMargin() + 1);
|
|
|
|
+ cellRect.setTotalHeight(rowPixPos[rowPixPos.length - 1] + cellRect.getMargin() + 1);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private static java.awt.Color fontColorCodec(Font fontAt, Workbook workbook) {
|
|
|
|
+ if (fontAt instanceof XSSFFont) {
|
|
|
|
+ XSSFColor xssfColor = ((XSSFFont) fontAt).getXSSFColor();
|
|
|
|
+ if (xssfColor != null) {
|
|
|
|
+ return Gradient.parse(xssfColor.getARGB());
|
|
|
|
+ }
|
|
|
|
+ return java.awt.Color.BLACK;
|
|
|
|
+ } else if (fontAt instanceof HSSFFont) {
|
|
|
|
+ // 未测试
|
|
|
|
+ return Gradient.parse(((HSSFFont) fontAt).getHSSFColor((HSSFWorkbook) workbook).getTriplet());
|
|
|
|
+ }
|
|
|
|
+ throw new RuntimeException("excel文件格式错误:既不是07格式也不是03格式");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 颜色转化
|
|
|
|
+ *
|
|
|
|
+ * @param fillForegroundColorColor
|
|
|
|
+ * @return
|
|
|
|
+ */
|
|
|
|
+ private static java.awt.Color colorCodec(Color fillForegroundColorColor) {
|
|
|
|
+ try {
|
|
|
|
+ return Gradient.parse(XSSFColor.toXSSFColor(fillForegroundColorColor).getARGB());
|
|
|
|
+ } catch (IllegalArgumentException e) {
|
|
|
|
+ return Gradient.parse(HSSFColor.toHSSFColor(fillForegroundColorColor).getTriplet());
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 读取单元格到字符串格式,按excel可见格式格式化字符串
|
|
|
|
+ *
|
|
|
|
+ * @param cell
|
|
|
|
+ * @return null 表示有问题
|
|
|
|
+ */
|
|
|
|
+ public static String readCellValueAsString(Cell cell) {
|
|
|
|
+ if (cell == null) {
|
|
|
|
+ return null;
|
|
|
|
+ } else {
|
|
|
|
+ switch (cell.getCellType()) {
|
|
|
|
+ case STRING:
|
|
|
|
+ return cell.getStringCellValue();
|
|
|
|
+ case NUMERIC: // 数字
|
|
|
|
+ if (DateUtil.isCellDateFormatted(cell)) {
|
|
|
|
+ // 日期格式,采用固定方式返回
|
|
|
|
+ return dateFormat.format(cell.getDateCellValue());
|
|
|
|
+ }
|
|
|
|
+ // 数字格式,使用excel的方式格式化 示例:百分比 0.00% 保留1位小数 0.0
|
|
|
|
+ String dataFormatString = cell.getCellStyle().getDataFormatString();
|
|
|
|
+ if (dataFormatString.equalsIgnoreCase("general")) {
|
|
|
|
+ return new DecimalFormat().format(cell.getNumericCellValue());
|
|
|
|
+ } else {
|
|
|
|
+ return new DecimalFormat(dataFormatString).format(cell.getNumericCellValue());
|
|
|
|
+ }
|
|
|
|
+ case FORMULA: // 公式
|
|
|
|
+ Workbook workbook = cell.getSheet().getWorkbook();
|
|
|
|
+ FormulaEvaluator evaluator;
|
|
|
|
+ CellValue cellValue;
|
|
|
|
+ if (workbook instanceof HSSFWorkbook) {
|
|
|
|
+ evaluator = new HSSFFormulaEvaluator((HSSFWorkbook) workbook);
|
|
|
|
+ cellValue = evaluator.evaluate(cell);
|
|
|
|
+ } else if (workbook instanceof XSSFWorkbook) {
|
|
|
|
+ evaluator = new XSSFFormulaEvaluator((XSSFWorkbook) workbook);
|
|
|
|
+ cellValue = evaluator.evaluate(cell);
|
|
|
|
+ } else {
|
|
|
|
+ throw new RuntimeException(String.format("单元格%d行%d列FormulaEvaluator创建失败, 无法识别workbook的类型",
|
|
|
|
+ cell.getRowIndex(), cell.getColumnIndex()));
|
|
|
|
+ }
|
|
|
|
+ switch (cellValue.getCellType()) {
|
|
|
|
+ case STRING:
|
|
|
|
+ return cellValue.getStringValue();
|
|
|
|
+ case NUMERIC:
|
|
|
|
+ if (DateUtil.isCellDateFormatted(cell)) {
|
|
|
|
+ // 日期格式,采用固定方式返回
|
|
|
|
+ return dateFormat.format(cell.getDateCellValue());
|
|
|
|
+ }
|
|
|
|
+ // 数字格式,使用excel的方式格式化 示例:百分比 0.00% 保留1位小数 0.0
|
|
|
|
+ String dataFormatString2 = cell.getCellStyle().getDataFormatString();
|
|
|
|
+ if (dataFormatString2.equalsIgnoreCase("general")) {
|
|
|
|
+ return new DecimalFormat().format(cell.getNumericCellValue());
|
|
|
|
+ } else {
|
|
|
|
+ return new DecimalFormat(dataFormatString2).format(cell.getNumericCellValue());
|
|
|
|
+ }
|
|
|
|
+ default:
|
|
|
|
+ return cellValue.formatAsString();
|
|
|
|
+ }
|
|
|
|
+ case BLANK:
|
|
|
|
+ return "";
|
|
|
|
+ case BOOLEAN:
|
|
|
|
+ return String.valueOf(cell.getBooleanCellValue());
|
|
|
|
+ case ERROR:
|
|
|
|
+ throw new RuntimeException(
|
|
|
|
+ String.format("单元格%d行%d列上有错误", cell.getRowIndex(), cell.getColumnIndex()));
|
|
|
|
+ case _NONE:
|
|
|
|
+ return null;
|
|
|
|
+ default:
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 判断单元格是否为合并单元格
|
|
|
|
+ *
|
|
|
|
+ * @param row
|
|
|
|
+ * @param col
|
|
|
|
+ * @param mergedRegions
|
|
|
|
+ * @return {-1. -1} 表示不是合并单元格, 是合并单元格且是第一个单元格返回{lastRow, lastCol},
|
|
|
|
+ * 是合并且不是第一个单元格返回{0, 0}
|
|
|
|
+ */
|
|
|
|
+ public static int[] isInMerged(int row, int col, List<CellRangeAddress> mergedRegions) {
|
|
|
|
+ int[] isInMergedStatus = { -1, -1 };
|
|
|
|
+ for (CellRangeAddress cellRangeAddress : mergedRegions) {
|
|
|
|
+ if (row == cellRangeAddress.getFirstRow() && col == cellRangeAddress.getFirstColumn()) {
|
|
|
|
+ isInMergedStatus[0] = cellRangeAddress.getLastRow();
|
|
|
|
+ isInMergedStatus[1] = cellRangeAddress.getLastColumn();
|
|
|
|
+ return isInMergedStatus;
|
|
|
|
+ }
|
|
|
|
+ if (row >= cellRangeAddress.getFirstRow() && row <= cellRangeAddress.getLastRow()) {
|
|
|
|
+ if (col >= cellRangeAddress.getFirstColumn() && col <= cellRangeAddress.getLastColumn()) {
|
|
|
|
+ isInMergedStatus[0] = 0;
|
|
|
|
+ isInMergedStatus[1] = 0;
|
|
|
|
+ return isInMergedStatus;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return isInMergedStatus;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 读取sheet中的条件背景颜色
|
|
|
|
+ * 当前仅支持三色渐进色条件背景
|
|
|
|
+ *
|
|
|
|
+ * @param sheet
|
|
|
|
+ * @return
|
|
|
|
+ */
|
|
|
|
+ private static Map<String, ThreeColorGradient> getConditionalBackgroundColor(Sheet sheet) {
|
|
|
|
+ SheetConditionalFormatting sheetConditionalFormatting = sheet.getSheetConditionalFormatting();
|
|
|
|
+ int numConditionalFormattings = sheetConditionalFormatting.getNumConditionalFormattings();
|
|
|
|
+ Row row;
|
|
|
|
+ Map<String, ThreeColorGradient> map = new HashMap<>();
|
|
|
|
+ // 遍历所有条件格式
|
|
|
|
+ for (int i = 0; i < numConditionalFormattings; i++) {
|
|
|
|
+ ConditionalFormatting conditionalFormattingAt = sheetConditionalFormatting.getConditionalFormattingAt(i);
|
|
|
|
+ CellRangeAddress[] formattingRanges = conditionalFormattingAt.getFormattingRanges();
|
|
|
|
+ // 遍历1项条件格式的所有区域
|
|
|
|
+ for (CellRangeAddress cellRangeAddress : formattingRanges) {
|
|
|
|
+ int firstColumn = cellRangeAddress.getFirstColumn();
|
|
|
|
+ int firstRow = cellRangeAddress.getFirstRow();
|
|
|
|
+ int lastColumn = cellRangeAddress.getLastColumn();
|
|
|
|
+ int lastRow = cellRangeAddress.getLastRow();
|
|
|
|
+ List<Double> values = new ArrayList<>();
|
|
|
|
+ ThreeColorGradient threeColorGradient = new ThreeColorGradient();
|
|
|
|
+ // 遍历条件格式包含的所有单元格,获取取值
|
|
|
|
+ for (int j = firstRow; j <= lastRow; j++) {
|
|
|
|
+ row = sheet.getRow(j);
|
|
|
|
+ for (int k = firstColumn; k <= lastColumn; k++) {
|
|
|
|
+ map.put(j + "-" + k, threeColorGradient);
|
|
|
|
+ values.add(row.getCell(k).getNumericCellValue());
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ // 排序
|
|
|
|
+ values.sort((o1, o2) -> Double.compare(o1, o2));
|
|
|
|
+ threeColorGradient.setStartValue(values.get(0));
|
|
|
|
+ threeColorGradient.setEndValue(values.get(values.size() - 1));
|
|
|
|
+ threeColorGradient.setMiddleValue(values.get(values.size() / 2));
|
|
|
|
+ // 渐进色颜色
|
|
|
|
+ for (int j = 0; j < conditionalFormattingAt.getNumberOfRules(); j++) {
|
|
|
|
+ ColorScaleFormatting colorScaleFormatting = conditionalFormattingAt.getRule(j)
|
|
|
|
+ .getColorScaleFormatting();
|
|
|
|
+ if (colorScaleFormatting != null) {
|
|
|
|
+ Color[] colors = colorScaleFormatting.getColors();
|
|
|
|
+ threeColorGradient.setStartColor(colorCodec(colors[0]));
|
|
|
|
+ threeColorGradient.setMiddleColor(colorCodec(colors[1]));
|
|
|
|
+ threeColorGradient.setEndColor(colorCodec(colors[2]));
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return map;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 复制单元格内容
|
|
|
|
+ public static void copyCellValue(Cell sourceCell, Cell targetCell) {
|
|
|
|
+ if (sourceCell == null) {
|
|
|
|
+ targetCell.setCellValue("");
|
|
|
|
+ } else {
|
|
|
|
+ switch (sourceCell.getCellType()) {
|
|
|
|
+ case BLANK:
|
|
|
|
+ targetCell.setCellValue("");
|
|
|
|
+ break;
|
|
|
|
+ case BOOLEAN:
|
|
|
|
+ targetCell.setCellValue(sourceCell.getBooleanCellValue());
|
|
|
|
+ break;
|
|
|
|
+ case ERROR:
|
|
|
|
+ targetCell.setCellErrorValue(sourceCell.getErrorCellValue());
|
|
|
|
+ break;
|
|
|
|
+ case FORMULA:
|
|
|
|
+ targetCell.setCellFormula(sourceCell.getCellFormula());
|
|
|
|
+ break;
|
|
|
|
+ case NUMERIC:
|
|
|
|
+ targetCell.setCellValue(sourceCell.getNumericCellValue());
|
|
|
|
+ break;
|
|
|
|
+ case STRING:
|
|
|
|
+ targetCell.setCellValue(sourceCell.getStringCellValue());
|
|
|
|
+ break;
|
|
|
|
+ default:
|
|
|
|
+ targetCell.setCellValue("");
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|