From 1f35c75edfde8d204e788f304929b1fb01ddb765 Mon Sep 17 00:00:00 2001 From: zhijie <1003392067@qq.com> Date: 星期日, 08 八月 2021 21:13:35 +0800 Subject: [PATCH] 1.PAQ简易版(中英泰)支持 2.支持完美水滴生成 --- src/main/java/com/ots/project/tool/report/PAQ/chart/PAQChart.java | 410 +++++++++++++++++++++++++++++++++++++++++++++ src/main/java/com/ots/project/tool/report/MAQ/base/RowData.java | 2 src/main/java/com/ots/common/utils/poi/WordUtil.java | 55 ++--- src/main/java/com/ots/project/tool/report/MAQ/base/SeriesData.java | 2 pom.xml | 12 + src/main/java/com/ots/project/tool/report/SAQ/chart/SAQChart.java | 6 6 files changed, 446 insertions(+), 41 deletions(-) diff --git a/pom.xml b/pom.xml index e0bd5d9..7fd0b74 100644 --- a/pom.xml +++ b/pom.xml @@ -280,6 +280,12 @@ <version>${poi.version}</version> </dependency> + <dependency> + <groupId>org.apache.poi</groupId> + <artifactId>ooxml-schemas</artifactId> + <version>1.4</version> + </dependency> + <!-- 绯婃秱宸ュ叿 --> <dependency> <groupId>cn.hutool</groupId> @@ -366,6 +372,12 @@ <version>1.1.6</version> </dependency> + <dependency> + <groupId>com.aspose</groupId> + <artifactId>words</artifactId> + <version>21.1</version> + </dependency> + </dependencies> <!--<build> <plugins> diff --git a/src/main/java/com/ots/common/utils/poi/WordUtil.java b/src/main/java/com/ots/common/utils/poi/WordUtil.java index 8ca167f..2f7182f 100644 --- a/src/main/java/com/ots/common/utils/poi/WordUtil.java +++ b/src/main/java/com/ots/common/utils/poi/WordUtil.java @@ -18,6 +18,7 @@ import com.ots.project.tool.report.JAQ.condition.Table2; import com.ots.project.tool.report.JAQ.condition.Table3; import com.ots.project.tool.report.JAQ.condition.Table4; +import com.ots.project.tool.report.PAQ.chart.PAQChart; import com.ots.project.tool.report.SAQ.chart.SAQChart; import org.apache.commons.collections.map.HashedMap; import org.apache.poi.ooxml.POIXMLDocument; @@ -433,9 +434,25 @@ public static boolean checkText(String text) { //鏇挎崲鏂囨湰鍖呭惈% if (text.indexOf("%") != -1 || StringUtils.equals(text, "N/A NONE")) { - return true; + //鍙湁%澶т簬1 鎵嶉�氳繃 + if(getCount(text) > 1){ + return true; + } + return false; } return false; + } + + //鍒ゆ柇%鍑虹幇鐨勬鏁� + public static int getCount(String text){ + //鏃ч暱搴� + int oldLength = text.length(); + text = text.replace("%", ""); + //鏂伴暱搴� + int newLength = text.length(); + //鍑虹幇娆℃暟 = 鏃ч暱搴� - 鏂伴暱搴� + int count = oldLength - newLength; + return count; } public static String changeValue(String runValue, Map<String, Object> textMap, XWPFRun run, XWPFParagraph paragraph, XWPFDocument document, int runPosition) throws IOException, org.apache.poi.openxml4j.exceptions.InvalidFormatException { @@ -605,38 +622,6 @@ } return rgbStr; } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - private static void changOtherPicture(XWPFParagraph paragraph) { @@ -863,8 +848,8 @@ changeTextBox(document, textMap); //璁剧疆鍥捐〃 - if (Objects.equals(reportType, ReportTypeEnum.SAQ.getCode()) || Objects.equals(reportType, ReportTypeEnum.PAQ.getCode())) { - SAQChart.changeChart(document, textMap); + if (Objects.equals(reportType, ReportTypeEnum.PAQ.getCode())) { + PAQChart.changeChart(document, textMap); } //鎻掑叆琛ㄦ牸 diff --git a/src/main/java/com/ots/project/tool/report/SAQ/chart/RowData.java b/src/main/java/com/ots/project/tool/report/MAQ/base/RowData.java similarity index 88% rename from src/main/java/com/ots/project/tool/report/SAQ/chart/RowData.java rename to src/main/java/com/ots/project/tool/report/MAQ/base/RowData.java index 8c84599..89a1ab0 100644 --- a/src/main/java/com/ots/project/tool/report/SAQ/chart/RowData.java +++ b/src/main/java/com/ots/project/tool/report/MAQ/base/RowData.java @@ -1,4 +1,4 @@ -package com.ots.project.tool.report.SAQ.chart; +package com.ots.project.tool.report.MAQ.base; import lombok.AllArgsConstructor; import lombok.Data; diff --git a/src/main/java/com/ots/project/tool/report/SAQ/chart/SeriesData.java b/src/main/java/com/ots/project/tool/report/MAQ/base/SeriesData.java similarity index 90% rename from src/main/java/com/ots/project/tool/report/SAQ/chart/SeriesData.java rename to src/main/java/com/ots/project/tool/report/MAQ/base/SeriesData.java index bbb10dc..8f92d0d 100644 --- a/src/main/java/com/ots/project/tool/report/SAQ/chart/SeriesData.java +++ b/src/main/java/com/ots/project/tool/report/MAQ/base/SeriesData.java @@ -1,4 +1,4 @@ -package com.ots.project.tool.report.SAQ.chart; +package com.ots.project.tool.report.MAQ.base; import lombok.AllArgsConstructor; import lombok.Data; diff --git a/src/main/java/com/ots/project/tool/report/PAQ/chart/PAQChart.java b/src/main/java/com/ots/project/tool/report/PAQ/chart/PAQChart.java new file mode 100644 index 0000000..3e90960 --- /dev/null +++ b/src/main/java/com/ots/project/tool/report/PAQ/chart/PAQChart.java @@ -0,0 +1,410 @@ +package com.ots.project.tool.report.PAQ.chart; + +import com.ots.project.tool.report.MAQ.base.RowData; +import com.ots.project.tool.report.MAQ.base.SeriesData; +import lombok.extern.slf4j.Slf4j; +import org.apache.poi.ooxml.POIXMLDocument; +import org.apache.poi.ooxml.POIXMLDocumentPart; +import org.apache.poi.xssf.usermodel.XSSFCell; +import org.apache.poi.xssf.usermodel.XSSFRow; +import org.apache.poi.xssf.usermodel.XSSFSheet; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.apache.poi.xwpf.usermodel.XWPFChart; +import org.apache.poi.xwpf.usermodel.XWPFDocument; +import org.openxmlformats.schemas.drawingml.x2006.chart.*; + +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.*; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * @description: PAQ鍥捐〃 鏁g偣鍥捐窡鏌卞舰鍥炬暟鎹彉鏇� + * @author: zhijie + * @create: 2021-06-07 23:31 + **/ +@Slf4j +public class PAQChart { + + private static String p_sde23,p_im24,p_incon25; + + public static void main(String[] args) throws IOException { + try (OutputStream os = new FileOutputStream("D:\\data\\鏋梍PAQ_IA_CN1.docx");XWPFDocument document = new XWPFDocument(POIXMLDocument.openPackage("D:\\data\\鏋梍PAQ_IA_CN.docx"))){ + Map<String, Object> textMap = new HashMap<String, Object>(); + textMap.put("P_SDE23","12"); + textMap.put("P_IM24","50"); + textMap.put("P_INCON25","90"); + changeChart(document,textMap); + document.write(os); + }catch (Exception e){ + e.printStackTrace(); + } + } + + /** + * 鏇挎崲PAQ鍥捐〃鏁版嵁 + * @param document 鏂囨。瀵硅薄 + * @param textMap 鎶ュ憡瀛楀吀閿�煎 + * @return + */ + public static boolean changeChart(XWPFDocument document, Map<String, Object> textMap){ + List<SeriesData> seriesDatas = initData(textMap); + if(seriesDatas == null){ + log.error("鏇挎崲PAQ鍥捐〃鏁版嵁,鍒濆鍖栨暟鎹け璐�!"); + return false; + } + //PAQ鍥捐〃鏁版嵁 + changePAQChart(document,seriesDatas); + return true; + } + + /** + * 鍒ゆ柇鏄惁涓虹┖ + * @param value + * @return + */ + public static boolean checkParamsIsNull(String... value) { + for (int i = 0; i < value.length; i++) { + if (Objects.isNull(value[i])) { + return true; + } + } + return false; + } + + /** + * 鍒濆鍖栨姤鍛婃暟鎹� + * @param textMap + * @return + */ + public static List<SeriesData> initData(Map<String, Object> textMap){ + //鑾峰彇鍛戒腑鏁板�� + p_sde23 = (String) textMap.get("P_SDE23"); + p_im24 = (String) textMap.get("P_IM24"); + p_incon25 = (String) textMap.get("P_INCON25"); + //鍒ゆ柇鏄惁涓虹┖ + if (checkParamsIsNull(p_sde23, p_im24, p_incon25)) { + return null; + } + Double P_SDE23 = Double.valueOf(p_sde23); + Double P_IM24 = Double.valueOf(p_im24); + Double P_INCON25 = Double.valueOf(p_incon25); + + // 娴嬭瘯鏁版嵁 + List<SeriesData> seriesDatas = Arrays.asList( + new SeriesData("涓汉鏁板�煎湪姝よ皟鏁�", Arrays.asList( + new RowData("涓汉鏁板�煎湪姝よ皟鏁�", P_INCON25), + new RowData("涓汉鏁板�煎湪姝よ皟鏁�", P_IM24), + new RowData("涓汉鏁板�煎湪姝よ皟鏁�", P_SDE23) + )), + new SeriesData("涓绘煴褰㈡暟鎹紙x杞达級1", Arrays.asList( + new RowData("涓绘煴褰㈡暟鎹紙x杞达級1", 0), + new RowData("涓绘煴褰㈡暟鎹紙x杞达級1", 5), + new RowData("涓绘煴褰㈡暟鎹紙x杞达級1", 5) + )), + new SeriesData("涓绘煴褰㈡暟鎹紙x杞达級2", Arrays.asList( + new RowData("涓绘煴褰㈡暟鎹紙x杞达級2", 5), + new RowData("涓绘煴褰㈡暟鎹紙x杞达級2", 5), + new RowData("涓绘煴褰㈡暟鎹紙x杞达級2", 5) + )), + new SeriesData("杈呭姪鏌卞舰鏁版嵁", Arrays.asList( + new RowData("杈呭姪鏌卞舰鏁版嵁", 100), + new RowData("杈呭姪鏌卞舰鏁版嵁", 95), + new RowData("杈呭姪鏌卞舰鏁版嵁", 95) + )), + new SeriesData("Y杞�", Arrays.asList( + new RowData("Y杞�", 27), + new RowData("Y杞�", 60), + new RowData("Y杞�", 93) + )) + ); + return seriesDatas; + } + + /** + * 鏇挎崲word鍥捐〃 鏁g偣鍥捐窡鏌卞舰鍥剧粍鍚堝浘褰� + * @param doc + * @param seriesDatas + */ + public static void changePAQChart(XWPFDocument doc,List<SeriesData> seriesDatas) { + try { + //鍔ㄦ�佸埛鏂板浘琛� + List<POIXMLDocumentPart> relations = doc.getRelations(); + for (POIXMLDocumentPart part : relations) { + if (part instanceof XWPFChart) { + // 鍥捐〃鍏冪礌 + XWPFChart chart = (XWPFChart) part; + + // 鏌ョ湅閲岄潰鐨勫浘琛ㄦ暟鎹紝鎵嶈兘鐭ラ亾鏄粈涔堝浘琛� + CTPlotArea plot = chart.getCTChart().getPlotArea(); + // excel鍐呯疆琛ㄦ牸 + XSSFWorkbook workbook = chart.getWorkbook(); + XSSFSheet sheet = workbook.getSheetAt(0); + + //鏁g偣鍥� + if (!plot.getScatterChartList().isEmpty()) { + CTScatterChart scatterChart = plot.getScatterChartArray(0); + //System.out.println("鏁g偣鍥緖"+plot.getScatterChartList().size()+"}"); + //鍒锋柊鍐呯疆excel鏁版嵁 + refreshExcel(seriesDatas, workbook, sheet); + workbook.write(chart.getPackagePart().getOutputStream()); + + //鏁g偣鍥炬暟鎹簮 XY鍧愭爣 + List<SeriesData> scatterDatas = new ArrayList<SeriesData>(); + scatterDatas.add(seriesDatas.get(0)); + scatterDatas.add(seriesDatas.get(4)); + int i = 0; + for (CTScatterSer ser : scatterChart.getSerList()) { + //鏇存柊姘存淮鏂囧瓧 + updateDLbls(ser); + //鏇存柊鏁g偣鍥剧紦瀛� + updateScatterChart(scatterDatas, ser.getXVal(), ser.getYVal()); + ++i; + } + } + //鏌卞舰鍥� + if (!plot.getBarChartList().isEmpty()) { + CTBarChart barChart = plot.getBarChartArray(0); + //System.out.println("鏌卞舰鍥緖"+plot.getScatterChartList().size()+"}"); + //鍒锋柊鍐呯疆excel鏁版嵁 + refreshExcel(seriesDatas, workbook, sheet); + workbook.write(chart.getPackagePart().getOutputStream()); + + //鏌卞舰鍥炬暟鎹簮 + List<SeriesData> barDatas = seriesDatas.subList(1,4); + //鍥犱负鏌卞舰鍥綜TBarSer娌℃寜excel椤哄簭璧� 璋冩崲鏁版嵁浣嶇疆淇濇寔瀵瑰簲 + Collections.swap(barDatas, 1, 2); + int i = 0; + for (CTBarSer ser : barChart.getSerList()) { + //鏇存柊鏌卞舰鍥炬暟鎹紦瀛� + updateBarChart(barDatas.get(i), ser.getVal()); + ++i; + } + } + } + } + + } catch (Exception e) { + e.printStackTrace(); + log.error("PAQGS鏇挎崲word鍥捐〃 鏁g偣鍥捐窡鏌卞舰鍥剧粍鍚堝浘褰㈠け璐ワ細{}",e); + } + } + + /** + * 鏇挎崲姘存淮鏁板�� + * @param ser + */ + private static void updateDLbls(CTScatterSer ser) { + Map<String, String> textMap = new HashMap<>(); + //鑾峰彇鍛戒腑鏁板�� + textMap.put("%P_SDE23%",p_sde23); + textMap.put("%P_IM24%",p_im24); + textMap.put("%P_INCON25%",p_incon25); + List<CTDLbl> lbls = ser.getDLbls().getDLblList(); + for (int i = 0; i < lbls.size(); i++) { + CTDLbl lbl = lbls.get(i); + String library = lbl.getTx().getRich().getPArray(0).getRArray(0).getT(); + log.info("姘存淮鏁板�兼浛鎹㈠墠{}:{}",i,lbl.getTx().getRich().getPArray(0).getRArray(0).getT()); + if(textMap.get(library) != null){ + lbl.getTx().getRich().getPArray(0).getRArray(0).setT(textMap.get(library)); + } + log.info("姘存淮鏁板�兼浛鎹㈠悗{}:{}",i,lbl.getTx().getRich().getPArray(0).getRArray(0).getT()); + } + } + + /** + * 鏇存柊鍥捐〃鐨勫叧鑱� excel + * + * @param seriesDatas + * @param workbook + * @param sheet + */ + protected static void refreshExcel(List<SeriesData> seriesDatas, XSSFWorkbook workbook, XSSFSheet sheet) { + XSSFRow title = sheet.getRow(0); + //閬嶅巻鏁版嵁鏁扮粍杩涜excel璧嬪�� + for (int i = 0; i < seriesDatas.size(); i++) { + SeriesData data = seriesDatas.get(i); + if (data.name != null && !data.name.isEmpty()) { + // 绗竴琛屾爣棰� + XSSFCell cell = title.getCell(i); + if (cell == null) { + cell = title.createCell(i + 1); + } + cell.setCellValue(data.name); + } + int size = data.value.size(); + //閬嶅巻鏁版嵁杩涜璧嬪�� + for (int j = 0; j < size; j++) { + //浠庣浜岃寮�濮嬭祴鍊� + XSSFRow row = sheet.getRow(j + 1); + if (row == null) { + row = sheet.createRow(j + 1); + } + RowData cellValu = data.value.get(j); + + //绗竴鍒楀紑濮嬭祴鍊� + XSSFCell cell = row.getCell(i); + if (cell == null) { + cell = row.createCell(i); + } + cell.setCellValue(cellValu.value); + } + //鍒犻櫎澶氫綑琛屾暟 + int lastRowNum = sheet.getLastRowNum(); + if (lastRowNum > size) { + for (int idx = lastRowNum; idx > size; idx--) { + sheet.removeRow(sheet.getRow(idx)); + } + } + } + } + + + /** + * 鏇存柊 鏁g偣鍥� 缂撳瓨鏁版嵁 + * + * @param seriesDatas 鏁版嵁 + * @param xDataSource X鍧愭爣鏁版嵁缂撳瓨 + * @param yDataSource Y鍧愭爣鏁版嵁缂撳瓨 + */ + protected static void updateScatterChart(List<SeriesData> seriesDatas, CTAxDataSource xDataSource, + CTNumDataSource yDataSource) { + + //鑾峰彇xy鍧愭爣鏁版嵁鏉℃暟 + long xNumCnt = xDataSource.getNumRef().getNumCache().getPtCount().getVal(); + long yNumCnt = yDataSource.getNumRef().getNumCache().getPtCount().getVal(); + + //鑾峰彇XY鏈�鏂版暟鎹� + List<RowData> xRowDatas = seriesDatas.get(0).getValue(); + int xRowDataSize = xRowDatas.size(); + List<RowData> yRowDatas = seriesDatas.get(1).getValue(); + int yRowDataSize = yRowDatas.size(); + + //鏇存柊X鍧愭爣缂撳瓨 + for (int i = 0; i < xRowDatas.size(); i++) { + RowData cellValu = xRowDatas.get(i); + CTNumVal val = xNumCnt > i ? xDataSource.getNumRef().getNumCache().getPtArray(i) + : xDataSource.getNumRef().getNumCache().addNewPt(); + val.setIdx(i); + val.setV(String.format("%.0f", cellValu.value)); + } + + //鏇存柊Y鍧愭爣缂撳瓨 + for (int i = 0; i < yRowDatas.size(); i++) { + RowData cellValu = yRowDatas.get(i); + CTNumVal val = yNumCnt > i ? yDataSource.getNumRef().getNumCache().getPtArray(i) + : yDataSource.getNumRef().getNumCache().addNewPt(); + val.setIdx(i); + val.setV(String.format("%.0f", cellValu.value)); + } + + // 鏇存柊瀵瑰簲excel鐨勮寖鍥� + xDataSource.getNumRef().setF( + replaceRowEnd(xDataSource.getNumRef().getF(), + xNumCnt, + xRowDataSize)); + yDataSource.getNumRef().setF( + replaceRowEnd(yDataSource.getNumRef().getF(), + yNumCnt, + yRowDataSize)); + + // 鍒犻櫎澶氱殑 + if (xNumCnt > xRowDataSize) { + for (int idx = xRowDataSize; idx < xNumCnt; idx++) { + xDataSource.getNumRef().getNumCache().removePt(xRowDataSize); + } + } + if (yNumCnt > yRowDataSize) { + for (int idx = yRowDataSize; idx < yNumCnt; idx++) { + yDataSource.getNumRef().getNumCache().removePt(yRowDataSize); + } + } + // 鏇存柊涓暟 + xDataSource.getNumRef().getNumCache().getPtCount().setVal(xRowDataSize); + // 鏇存柊涓暟 + yDataSource.getNumRef().getNumCache().getPtCount().setVal(yRowDataSize); + } + + + /** + * 鏇存柊 鏌卞舰鍥� 鐨勭紦瀛樻暟鎹� + * + * @param seriesDatas 鏁版嵁 + * @param numDataSource 鏁版嵁鐨勭紦瀛� + */ + protected static void updateBarChart(SeriesData seriesDatas, CTNumDataSource numDataSource) { + //鑾峰彇鏌卞舰鍥炬暟鎹暟閲� + long ptNumCnt = numDataSource.getNumRef().getNumCache().getPtCount().getVal(); + int dataSize = seriesDatas.value.size(); + for (int i = 0; i < dataSize; i++) { + RowData cellValu = seriesDatas.value.get(i); + CTNumVal val = ptNumCnt > i ? numDataSource.getNumRef().getNumCache().getPtArray(i) + : numDataSource.getNumRef().getNumCache().addNewPt(); + val.setIdx(i); + val.setV(String.format("%.0f", cellValu.value)); + + } + + // 鏇存柊瀵瑰簲excel鐨勮寖鍥� + numDataSource.getNumRef().setF( + replaceRowEnd(numDataSource.getNumRef().getF(), + ptNumCnt, + dataSize)); + + // 鍒犻櫎澶氱殑 + if (ptNumCnt > dataSize) { + for (int idx = dataSize; idx < ptNumCnt; idx++) { + numDataSource.getNumRef().getNumCache().removePt(dataSize); + } + } + // 鏇存柊涓暟 + numDataSource.getNumRef().getNumCache().getPtCount().setVal(dataSize); + } + + + /** + * 鏇挎崲 褰㈠锛� Sheet1!$A$2:$A$4 鐨勫瓧绗� + * + * @param range + * @return + */ + public static String replaceRowEnd(String range, long oldSize, long newSize) { + Pattern pattern = Pattern.compile("(:\\$[A-Z]+\\$)(\\d+)"); + Matcher matcher = pattern.matcher(range); + if (matcher.find()) { + long old = Long.parseLong(matcher.group(2)); + return range.replaceAll("(:\\$[A-Z]+\\$)(\\d+)", "$1" + Long.toString(old - oldSize + newSize)); + } + return range; + } + + /** + * 鑾峰彇鍥捐〃鏈夊摢浜涚被鍨� + * @param part + */ + public static void getChartType(POIXMLDocumentPart part){ + XWPFChart chart = (XWPFChart) part; + //鏍规嵁灞炴�х涓�鍒楀悕绉板垏鎹㈡暟鎹被鍨� + CTChart ctChart = chart.getCTChart(); + CTPlotArea plotArea = ctChart.getPlotArea(); + + if (!plotArea.getBarChartList().isEmpty()) { + System.out.println("鏌辩姸鍥緖"+plotArea.getBarChartList().size()+"}"); + } + if (!plotArea.getPieChartList().isEmpty()) { + System.out.println("楗煎浘{"+plotArea.getPieChartList().size()+"}"); + } + if (!plotArea.getLineChartList().isEmpty()) { + System.out.println("绾垮舰鍥緖"+plotArea.getLineChartList().size()+"}"); + } + if (!plotArea.getBar3DChartList().isEmpty()) { + System.out.println("鏌辩姸鍥�3D{"+plotArea.getBar3DChartList().size()+"}"); + } + if (!plotArea.getScatterChartList().isEmpty()) { + System.out.println("鏁g偣鍥緖"+plotArea.getScatterChartList().size()+"}"); + } + } + +} diff --git a/src/main/java/com/ots/project/tool/report/SAQ/chart/SAQChart.java b/src/main/java/com/ots/project/tool/report/SAQ/chart/SAQChart.java index 47e6fb5..4a532a3 100644 --- a/src/main/java/com/ots/project/tool/report/SAQ/chart/SAQChart.java +++ b/src/main/java/com/ots/project/tool/report/SAQ/chart/SAQChart.java @@ -1,9 +1,10 @@ package com.ots.project.tool.report.SAQ.chart; +import com.ots.project.tool.report.MAQ.base.RowData; +import com.ots.project.tool.report.MAQ.base.SeriesData; import lombok.extern.slf4j.Slf4j; import org.apache.poi.ooxml.POIXMLDocument; import org.apache.poi.ooxml.POIXMLDocumentPart; -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.xssf.usermodel.XSSFCell; import org.apache.poi.xssf.usermodel.XSSFRow; import org.apache.poi.xssf.usermodel.XSSFSheet; @@ -12,9 +13,6 @@ import org.apache.poi.xwpf.usermodel.XWPFDocument; import org.openxmlformats.schemas.drawingml.x2006.chart.*; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; import java.io.IOException; import java.util.*; import java.util.regex.Matcher; -- Gitblit v1.9.1