package com.hui.core.report.util; import com.hui.core.report.model.*; import org.apache.commons.lang3.StringUtils; import org.apache.poi.POIXMLDocumentPart; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.xslf.usermodel.*; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.apache.xmlbeans.XmlObject; import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * <b><code>ConfigResolver</code></b> * <p/> * Description:解读配置文件DEMO * <p/> * <b>Creation Time:</b> 2018/10/23 22:42. * * @author Hu Weihui */ public class ConfigResolver { //就是执行SQL的一个工具类。这里不提供。因为不是我写的。可以用JdbcTemplate代替。不过要修改下ConfigResolver的代码。 //往后修改成JdbcTemplate再提交。测试运行的DEMO代码不需要这个工具类 private SqlAutoMapper sqlAutoMapper; private static final String XML_OBJ_PATH = "declare namespace p='http://schemas.openxmlformats.org/presentationml/2006/main' .//*/p:cNvPr"; private static final String CHART_SQL = "chart.sql"; private static final String CHART_COL_ROW_VALUE = "chart.col.row.value"; private static final String TABLE_SQL = "table.sql"; /** * 分析PPT配置文件. * * @param templateFilePath the template file path * @param paramsMap the params map * @return the map * @throws IOException the io exception * @since hui_project 1.0.0 */ public Map<Integer, SlideData> analysisPowerPointConfig(String templateFilePath, Map<String, Object> paramsMap) throws IOException { Map<Integer, SlideData> slideDataMap = new HashMap<>(); FileInputStream fileInputStream = new FileInputStream(templateFilePath); XMLSlideShow ppt = new XMLSlideShow(fileInputStream); List<XSLFSlide> slideList = ppt.getSlides(); for (XSLFSlide slide : slideList) { SlideData slideData = loadSlideConfig(slide,paramsMap); slideDataMap.put(slide.getSlideNumber(), slideData); } return slideDataMap; } /** * 读取每页配置文件. * * @param slide the slide * @param paramsMap the params map * @return the slide data * @throws IOException the io exception * @since hui_project 1.0.0 */ private SlideData loadSlideConfig(XSLFSlide slide, Map<String, Object> paramsMap) throws IOException { SlideData slideData = new SlideData(); List<ChartData> chartDataList = new ArrayList<>(); Map<String, String> textMap = new HashMap<>(); List<TableData> tableDataList = new ArrayList<>(); List<POIXMLDocumentPart> partList = slide.getRelations(); for (POIXMLDocumentPart part : partList) { if (part instanceof XSLFChart) { List<ChartSeries> seriesDataList = getDataMap((XSLFChart) part, paramsMap); ChartData chartData = new ChartData(); chartData.setChartSeriesList(seriesDataList); chartDataList.add(chartData); } } List<XSLFShape> shapeList = slide.getShapes(); for (XSLFShape shape : shapeList) { //判断文本框 if (shape instanceof XSLFTextShape) { Map<String, String> tempMap = getDataMap((XSLFTextShape) shape,paramsMap); textMap.putAll(tempMap); } //判断表格 if (shape instanceof XSLFTable) { List<TableRowData> tempList = getDataMap((XSLFTable) shape); TableData tableData = new TableData(); tableData.setTableRowDataList(tempList); tableDataList.add(tableData); } } slideData.setTextMap(textMap); slideData.setTableDataList(tableDataList); slideData.setChartDataList(chartDataList); slideData.setSlidePage(slide.getSlideNumber()); return slideData; } /** * 获取表格需要渲染的值 * * @param table * @return */ public List<TableRowData> getDataMap(XSLFTable table) { Map<String, String> dataMap = new HashMap<>(); XSLFTableCell cell = table.getCell(0, 0); String sql=""; if (cell != null) { String text = cell.getText(); Map<String, String> configMap = getConfig(text); for (String key : configMap.keySet()) { if (TABLE_SQL.equals(key)){ sql = configMap.get(key); } } List<Map<String, Object>> sqlDataList = sqlAutoMapper.selectList(sql); return analysisTableData(sqlDataList); } return new ArrayList<>(); } /** * 分析表格数据. * * @param sqlDataList the sql data list * @return the list * @since hui_project 1.0.0 */ private List<TableRowData> analysisTableData(List<Map<String, Object>> sqlDataList){ List<TableRowData> tableRowDataList = new ArrayList<>(); for (Map<String, Object> stringObjectMap : sqlDataList) { TableRowData tableData = new TableRowData(); List<String> dataList = new ArrayList<>(); for (String key:stringObjectMap.keySet()){ String data = (String) stringObjectMap.get(key); dataList.add(data); } tableData.setDataList(dataList); tableRowDataList.add(tableData); } return tableRowDataList; } /** * 获取文本框里面的替换值 * * @param text * @return */ public Map<String, String> getDataMap(XSLFTextShape text, Map<String,Object> paramsMap) { Map<String, String> dataMap = new HashMap<>(); XmlObject[] xmlObjectArray = text.getXmlObject().selectPath(XML_OBJ_PATH); if (xmlObjectArray.length > 0) { CTNonVisualDrawingProps props = (CTNonVisualDrawingProps) (CTNonVisualDrawingProps.class.isInstance(xmlObjectArray[0]) ? xmlObjectArray[0] : null); if (props != null) { Map<String, String> configMap = getConfig(props.getDescr()); for (String key : configMap.keySet()) { String dataKey = key.substring(0,key.indexOf(".")); String sql = configMap.get(key); String dataValue = sqlAutoMapper.selectOne(sql, paramsMap,String.class); dataMap.put(dataKey, dataValue); } } } return dataMap; } /** * 获取表格数据. * * @param chart the chart * @param paramsMap the params map * @return the data map * @throws IOException the io exception * @since hui_project 1.0.0 */ public List<ChartSeries> getDataMap(XSLFChart chart, Map<String, Object> paramsMap) throws IOException { POIXMLDocumentPart excelPart = chart.getRelations().get(0); InputStream excelInputStream = excelPart.getPackagePart().getInputStream(); Workbook workbook = new XSSFWorkbook(excelInputStream); Sheet sheet = workbook.getSheetAt(0); String config = sheet.getRow(25).getCell(25).getStringCellValue(); excelInputStream.close(); workbook.close(); Map<String, String> configMap = getConfig(config); String sql = ""; Map<String, String> colRowValueMap = new HashMap<>(); for (String key : configMap.keySet()) { if (CHART_SQL.equals(key)) { sql = configMap.get(key); } else if (CHART_COL_ROW_VALUE.equals(key)) { String colRowValue = configMap.get(key); String colRowValueArray[] = colRowValue.split(":"); for (String s : colRowValueArray) { String mapKey = s.substring(0, s.indexOf(",")); String mapValue = s.substring(s.indexOf(",") + 1, s.length()); colRowValueMap.put(mapKey, mapValue); } } } return analysisGraphData(sql, colRowValueMap, paramsMap); } /** * sql获取表数据. * * @param sql the sql * @param colRowValueMap the col row value map * @param paramsMap the params map * @return the list * @since hui_project 1.0.0 */ private List<ChartSeries> analysisGraphData(String sql, Map<String,String> colRowValueMap, Map<String,Object> paramsMap) { String colName = colRowValueMap.get("col"); String rowName = colRowValueMap.get("row"); String valueName = colRowValueMap.get("value"); List<Map<String, Object>> dataList = sqlAutoMapper.selectList(sql,paramsMap); List<ChartSeries> seriesDataList = new ArrayList<>(); Map<String, ChartSeries> tmpMap = new HashMap<>(); for (Map<String, Object> dataMap : dataList) { String _colName = (String)dataMap.get(colName); String _rowName = (String)dataMap.get(rowName); Double _value = Double.parseDouble((String) dataMap.get(valueName)); if (tmpMap.get(_colName)!=null){ ChartSeries seriesData = tmpMap.get(_colName); seriesData.getChartCategoryList().add(new ChartCategory(_rowName, _value)); }else { List<ChartCategory> categoryDataList = new ArrayList<>(); categoryDataList.add(new ChartCategory(_rowName, _value)); ChartSeries seriesData = new ChartSeries(); seriesData.setSeriesName(_colName); seriesData.setChartCategoryList(categoryDataList); tmpMap.put(_colName, seriesData); } } for (String key:tmpMap.keySet()){ seriesDataList.add(tmpMap.get(key)); } return seriesDataList; } /** * 配置转成Map * * @param config the config * @return the config * @since hui_project 1.0.0 */ private Map getConfig(String config) { config = config.trim(); Map<String, String> configMap = new HashMap<>(); if (StringUtils.isNotBlank(config) && config.length() >= 8) { int i = config.indexOf("<config>"); int i1 = config.indexOf("</config>"); config = config.substring(config.indexOf("<config>") + 8, config.indexOf("</config>")); String[] keyValues = config.split(";"); for (String keyValue : keyValues) { keyValue = keyValue.trim(); if (StringUtils.isNotBlank(keyValue)) { int index = keyValue.indexOf("="); String key = keyValue.substring(0, index); String value = keyValue.substring(index + 1); configMap.put(key, value); } } } return configMap; } /** * 去除配置. * * @param textShape the text shape * @since hui_project 1.0.0 */ public void removePPTConfig(XSLFTextShape textShape) { XmlObject[] xmlObjectArray = textShape.getXmlObject().selectPath(XML_OBJ_PATH); if (xmlObjectArray.length > 0) { CTNonVisualDrawingProps props = (CTNonVisualDrawingProps) (CTNonVisualDrawingProps.class.isInstance(xmlObjectArray[0]) ? xmlObjectArray[0] : null); if (props != null) { props.setDescr(""); } } } }