package net.unit8.axebomber.parser; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.commons.lang.StringUtils; import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.util.CellRangeAddress; public class Range { private static final Pattern R1C1 = Pattern.compile("(R(\\d+)?)?(C(\\d+)?)?"); private int x1, x2, y1, y2; private Sheet sheet; private List<Integer> labelIndexes; private int regionIndex; protected Range() {} public Range(Cell beginCell, Cell endCell) { } public static Range parse(String rangeStr, Sheet sheet) { String[] ranges = StringUtils.split(rangeStr, ":", 2); Range range = new Range(); if (ranges.length == 1) { Matcher m = R1C1.matcher(ranges[0]); if (m.find()) { range.y1 = parseIndex(m, 1, -1); range.y2 = parseIndex(m, 1, Integer.MAX_VALUE); range.x1 = parseIndex(m, 3, -1); range.x2 = parseIndex(m, 3, Integer.MAX_VALUE); } else throw new IllegalArgumentException(rangeStr); } else if (ranges.length == 2) { Matcher m = R1C1.matcher(ranges[0]); if (m.find()) { range.y1 = parseIndex(m, 1, -1); range.x1 = parseIndex(m, 3, -1); } m = R1C1.matcher(ranges[1]); if (m.find()) { range.y2 = parseIndex(m, 1, Integer.MAX_VALUE); range.x2 = parseIndex(m, 3, Integer.MAX_VALUE); } } else { throw new IllegalArgumentException(rangeStr); } if (range.y1 > range.y2) { int tmp = range.y2; range.y2 = range.y1; range.y1 = tmp; } if (range.x1 > range.x2) { int tmp = range.x2; range.x2 = range.x1; range.x1 = tmp; } range.sheet = sheet; return range; } private static int parseIndex(Matcher m, int i, int defaultValue) { if (StringUtils.isEmpty(m.group(i))) { return defaultValue; } else { return StringUtils.isEmpty(m.group(i+1)) ? 0 : Integer.parseInt(m.group(i+1)); } } public int getFirstRowNum() { return y1; } public int getLastRowNum() { return y2; } public int getFirstColumnNum() { return x1; } public int getLastColumnNum() { return x2; } public Sheet getSheet() { return sheet; } public void setStyle(Style style) { int top = Math.max(y1, sheet.getSubstance().getFirstRowNum()); int bottom = Math.min(y2, sheet.getSubstance().getLastRowNum()); for (int i = top; i <= bottom; i++) { Row row = sheet.getRow(i); int left = Math.max(x1, row.getSubstance().getFirstCellNum()); int right = Math.min(x2, row.getSubstance().getLastCellNum()); for(int j = left; j <= right; j++) { int borderBits = 0; if (i == top) borderBits += StyleManager.BORDER_TOP; else borderBits += (StyleManager.BORDER_TOP * 2); if (i == bottom) borderBits += StyleManager.BORDER_BOTTOM; else borderBits += (StyleManager.BORDER_BOTTOM * 2); if (j == left) { borderBits += StyleManager.BORDER_LEFT; } else if (labelIndexes.contains(j)) { borderBits += (StyleManager.BORDER_LEFT * 2); } if (j == right) borderBits += StyleManager.BORDER_RIGHT; Cell cell = row.cell(j); CellStyle cellStyle = StyleManager.getInstance(sheet.getSubstance().getWorkbook()).getStyle(style, borderBits); cell.getSubstance().setCellStyle(cellStyle); } } } public Range gridize() { int top = Math.max(y1, sheet.getSubstance().getFirstRowNum()); Row row = sheet.getRow(top); int left = Math.max(x1, row.getSubstance().getFirstCellNum()); int right = Math.min(x2, row.getSubstance().getLastCellNum()); for (int i=left; i <= right; i++) { sheet.getSubstance().setColumnWidth(i, 746); } return this; } public Range merge() { regionIndex = sheet.getSubstance().addMergedRegion(new CellRangeAddress(y1, y2, x1, x2)); return this; } public Range unmerge() { sheet.getSubstance().removeMergedRegion(regionIndex); return this; } public void setLabelColumns(Map<String, Integer> labelColumns) { this.labelIndexes = new ArrayList<Integer>(labelColumns.values()); Collections.sort(labelIndexes); int lastIndex = labelIndexes.get(labelIndexes.size() - 1); if (x2 < lastIndex) { x2 = lastIndex; } } public void setValue(Object value) { sheet.cell(x1, y1).setValue(value); } public int to_i() { return sheet.cell(x1, y1).to_i(); } @Override public String toString() { return sheet.cell(x1, y1).toString(); } }