From e52593d3f6a69dec41bc3cdfe15112239014c4c6 Mon Sep 17 00:00:00 2001 From: xfworld Date: Wed, 13 Jan 2016 09:38:48 +0800 Subject: [PATCH] =?UTF-8?q?Excel=20Charts=E6=9E=84=E5=BB=BA=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../graph/builder/ExcelChartBuildService.java | 262 ++++++++++++++++++ .../graph/constant/ExcelGraphElementType.java | 16 ++ .../excel/graph/constant/ExcelGraphType.java | 17 ++ .../poi/excel/graph/entity/ExcelGraph.java | 22 ++ .../excel/graph/entity/ExcelGraphDefined.java | 70 +++++ .../excel/graph/entity/ExcelGraphElement.java | 64 +++++ .../excel/graph/entity/ExcelTitleCell.java | 44 +++ .../poi/excel/graph/package-info.java | 10 + .../poi/util/PoiExcelGraphDataUtil.java | 55 ++++ .../excel/entity/vo/MapExcelConstants.java | 2 +- .../entity/vo/MapExcelGraphConstants.java | 19 ++ .../poi/excel/view/MapGraphExcelView.java | 82 ++++++ 12 files changed, 662 insertions(+), 1 deletion(-) create mode 100644 easypoi-base/src/main/java/org/jeecgframework/poi/excel/graph/builder/ExcelChartBuildService.java create mode 100644 easypoi-base/src/main/java/org/jeecgframework/poi/excel/graph/constant/ExcelGraphElementType.java create mode 100644 easypoi-base/src/main/java/org/jeecgframework/poi/excel/graph/constant/ExcelGraphType.java create mode 100644 easypoi-base/src/main/java/org/jeecgframework/poi/excel/graph/entity/ExcelGraph.java create mode 100644 easypoi-base/src/main/java/org/jeecgframework/poi/excel/graph/entity/ExcelGraphDefined.java create mode 100644 easypoi-base/src/main/java/org/jeecgframework/poi/excel/graph/entity/ExcelGraphElement.java create mode 100644 easypoi-base/src/main/java/org/jeecgframework/poi/excel/graph/entity/ExcelTitleCell.java create mode 100644 easypoi-base/src/main/java/org/jeecgframework/poi/excel/graph/package-info.java create mode 100644 easypoi-base/src/main/java/org/jeecgframework/poi/util/PoiExcelGraphDataUtil.java create mode 100644 easypoi-web/src/main/java/org/jeecgframework/poi/excel/entity/vo/MapExcelGraphConstants.java create mode 100644 easypoi-web/src/main/java/org/jeecgframework/poi/excel/view/MapGraphExcelView.java diff --git a/easypoi-base/src/main/java/org/jeecgframework/poi/excel/graph/builder/ExcelChartBuildService.java b/easypoi-base/src/main/java/org/jeecgframework/poi/excel/graph/builder/ExcelChartBuildService.java new file mode 100644 index 0000000..bcf40f9 --- /dev/null +++ b/easypoi-base/src/main/java/org/jeecgframework/poi/excel/graph/builder/ExcelChartBuildService.java @@ -0,0 +1,262 @@ +/** + * + */ +package org.jeecgframework.poi.excel.graph.builder; + +import java.util.List; + +import org.apache.commons.lang3.StringUtils; +import org.apache.poi.ss.usermodel.Chart; +import org.apache.poi.ss.usermodel.ClientAnchor; +import org.apache.poi.ss.usermodel.Drawing; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.usermodel.Workbook; +import org.apache.poi.ss.usermodel.charts.AxisCrosses; +import org.apache.poi.ss.usermodel.charts.AxisPosition; +import org.apache.poi.ss.usermodel.charts.ChartAxis; +import org.apache.poi.ss.usermodel.charts.ChartDataSource; +import org.apache.poi.ss.usermodel.charts.ChartLegend; +import org.apache.poi.ss.usermodel.charts.DataSources; +import org.apache.poi.ss.usermodel.charts.LegendPosition; +import org.apache.poi.ss.usermodel.charts.LineChartData; +import org.apache.poi.ss.usermodel.charts.ScatterChartData; +import org.apache.poi.ss.usermodel.charts.ValueAxis; +import org.apache.poi.ss.util.CellRangeAddress; +import org.jeecgframework.poi.excel.graph.constant.ExcelGraphElementType; +import org.jeecgframework.poi.excel.graph.constant.ExcelGraphType; +import org.jeecgframework.poi.excel.graph.entity.ExcelGraph; +import org.jeecgframework.poi.excel.graph.entity.ExcelGraphElement; +import org.jeecgframework.poi.excel.graph.entity.ExcelTitleCell; +import org.jeecgframework.poi.util.PoiCellUtil; +import org.jeecgframework.poi.util.PoiExcelGraphDataUtil; + +import com.google.common.collect.Lists; + +/** + * @author xfworld + * @since 2015-12-30 + * @version 1.0 + * + */ +public class ExcelChartBuildService +{ + /** + * + * @param workbook + * @param graph + * @param build 通过实时数据行来重新计算图形定义 + * @param append + */ + public static void createExcelChart(Workbook workbook,List graphList,Boolean build,Boolean append) + { + if(workbook!=null&&graphList!=null){ + //设定默认第一个sheet为数据项 + Sheet dataSouce=workbook.getSheetAt(0); + if(dataSouce!=null){ + buildTitle(dataSouce,graphList); + + if(build){ + PoiExcelGraphDataUtil.buildGraphData(dataSouce, graphList); + } + if(append){ + buildExcelChart(dataSouce, dataSouce, graphList); + }else{ + Sheet sheet=workbook.createSheet("图形界面"); + buildExcelChart(dataSouce, sheet, graphList); + } + } + + } + } + + /** + * 构建基础图形 + * @param drawing + * @param anchor + * @param dataSourceSheet + * @param graph + */ + private static void buildExcelChart(Drawing drawing,ClientAnchor anchor,Sheet dataSourceSheet,ExcelGraph graph){ + Chart chart = drawing.createChart(anchor); + ChartLegend legend = chart.getOrCreateLegend(); + legend.setPosition(LegendPosition.TOP_RIGHT); + + ChartAxis bottomAxis = chart.getChartAxisFactory().createCategoryAxis(AxisPosition.BOTTOM); + ValueAxis leftAxis = chart.getChartAxisFactory().createValueAxis(AxisPosition.LEFT); + leftAxis.setCrosses(AxisCrosses.AUTO_ZERO); + ExcelGraphElement categoryElement=graph.getCategory(); + + ChartDataSource categoryChart; + if(categoryElement!=null&&categoryElement.getElementType()==ExcelGraphElementType.StringType){ + categoryChart=DataSources.fromStringCellRange(dataSourceSheet, new CellRangeAddress(categoryElement.getStartRowNum(),categoryElement.getEndRowNum(),categoryElement.getStartColNum(),categoryElement.getEndColNum())); + }else{ + categoryChart=DataSources.fromNumericCellRange(dataSourceSheet, new CellRangeAddress(categoryElement.getStartRowNum(),categoryElement.getEndRowNum(),categoryElement.getStartColNum(),categoryElement.getEndColNum())); + } + + List valueList=graph.getValueList(); + List> chartValueList=Lists.newArrayList(); + if(valueList!=null&&valueList.size()>0){ + for(ExcelGraphElement ele:valueList){ + ChartDataSource source=DataSources.fromNumericCellRange(dataSourceSheet, new CellRangeAddress(ele.getStartRowNum(),ele.getEndRowNum(),ele.getStartColNum(),ele.getEndColNum())); + chartValueList.add(source); + } + } + + if(graph.getGraphType()==ExcelGraphType.LineChart){ + LineChartData data = chart.getChartDataFactory().createLineChartData(); + buildLineChartData(data, categoryChart, chartValueList, graph.getTitle()); + chart.plot(data, bottomAxis, leftAxis); + } + else + { + ScatterChartData data=chart.getChartDataFactory().createScatterChartData(); + buildScatterChartData(data, categoryChart, chartValueList,graph.getTitle()); + chart.plot(data, bottomAxis, leftAxis); + } + } + + + + + /** + * 构建多个图形对象 + * @param dataSourceSheet + * @param tragetSheet + * @param graphList + */ + private static void buildExcelChart(Sheet dataSourceSheet,Sheet tragetSheet,List graphList){ + int len=graphList.size(); + if(len==1) + { + buildExcelChart(dataSourceSheet, tragetSheet, graphList.get(0)); + } + else + { + int drawStart=0; + int drawEnd=20; + Drawing drawing = tragetSheet.createDrawingPatriarch(); + for(int i=0;i0){ + + }else{ + for(int i=0;i graphList){ + if(graphList!=null&&graphList.size()>0){ + for(ExcelGraph graph:graphList){ + if(graph!=null) + { + buildTitle(sheet, graph); + } + } + } + } + + /** + * + * @param data + * @param categoryChart + * @param chartValueList + * @param title + */ + private static void buildLineChartData(LineChartData data,ChartDataSource categoryChart,List> chartValueList,List title){ + if(chartValueList.size()==title.size()) + { + int len=title.size(); + for(int i=0;i source:chartValueList){ + String _title=title.get(i); + if(StringUtils.isNotBlank(_title)){ + data.addSerie(categoryChart, source).setTitle(_title); + }else{ + data.addSerie(categoryChart, source); + } + } + } + } + + /** + * + * @param data + * @param categoryChart + * @param chartValueList + * @param title + */ + private static void buildScatterChartData(ScatterChartData data,ChartDataSource categoryChart,List> chartValueList,List title){ + if(chartValueList.size()==title.size()) + { + int len=title.size(); + for(int i=0;i source:chartValueList){ + String _title=title.get(i); + if(StringUtils.isNotBlank(_title)){ + data.addSerie(categoryChart, source).setTitle(_title); + }else{ + data.addSerie(categoryChart, source); + } + } + } + } + + +} diff --git a/easypoi-base/src/main/java/org/jeecgframework/poi/excel/graph/constant/ExcelGraphElementType.java b/easypoi-base/src/main/java/org/jeecgframework/poi/excel/graph/constant/ExcelGraphElementType.java new file mode 100644 index 0000000..db85314 --- /dev/null +++ b/easypoi-base/src/main/java/org/jeecgframework/poi/excel/graph/constant/ExcelGraphElementType.java @@ -0,0 +1,16 @@ +/** + * + */ +package org.jeecgframework.poi.excel.graph.constant; + +/** + * @author xfworld + * @since 2015-12-30 + * @version 1.0 + * 定义元素类型 + */ +public interface ExcelGraphElementType +{ + public static final Integer StringType=1; + public static final Integer NumericType=2; +} diff --git a/easypoi-base/src/main/java/org/jeecgframework/poi/excel/graph/constant/ExcelGraphType.java b/easypoi-base/src/main/java/org/jeecgframework/poi/excel/graph/constant/ExcelGraphType.java new file mode 100644 index 0000000..627797e --- /dev/null +++ b/easypoi-base/src/main/java/org/jeecgframework/poi/excel/graph/constant/ExcelGraphType.java @@ -0,0 +1,17 @@ +/** + * + */ +package org.jeecgframework.poi.excel.graph.constant; + +/** + * @author xfworld + * @since 2015-12-30 + * @version 1.0 + * 定义图形类型 + */ +public interface ExcelGraphType +{ + public static final Integer LineChart=1; + public static final Integer ScatterChart=2; + +} diff --git a/easypoi-base/src/main/java/org/jeecgframework/poi/excel/graph/entity/ExcelGraph.java b/easypoi-base/src/main/java/org/jeecgframework/poi/excel/graph/entity/ExcelGraph.java new file mode 100644 index 0000000..169f0e2 --- /dev/null +++ b/easypoi-base/src/main/java/org/jeecgframework/poi/excel/graph/entity/ExcelGraph.java @@ -0,0 +1,22 @@ +/** + * + */ +package org.jeecgframework.poi.excel.graph.entity; + +import java.util.List; + +/** + * @author xfworld + * @since 2016-1-7 + * @version 1.0 + * @see com.dawnpro.core.export.excel.model.ExcelGraph + * + */ +public interface ExcelGraph +{ + public ExcelGraphElement getCategory(); + public List getValueList(); + public Integer getGraphType(); + public List getTitleCell(); + public List getTitle(); +} diff --git a/easypoi-base/src/main/java/org/jeecgframework/poi/excel/graph/entity/ExcelGraphDefined.java b/easypoi-base/src/main/java/org/jeecgframework/poi/excel/graph/entity/ExcelGraphDefined.java new file mode 100644 index 0000000..3729c16 --- /dev/null +++ b/easypoi-base/src/main/java/org/jeecgframework/poi/excel/graph/entity/ExcelGraphDefined.java @@ -0,0 +1,70 @@ +/** + * + */ +package org.jeecgframework.poi.excel.graph.entity; + +import java.util.List; + +import org.jeecgframework.poi.excel.graph.constant.ExcelGraphType; + +import com.google.common.collect.Lists; + +/** + * @author xfworld + * @since 2015-12-30 + * @version 1.0 + * + */ +public class ExcelGraphDefined implements ExcelGraph +{ + private ExcelGraphElement category; + public List valueList=Lists.newArrayList(); + public List titleCell=Lists.newArrayList(); + private Integer graphType=ExcelGraphType.LineChart; + public List title=Lists.newArrayList(); + + public ExcelGraphElement getCategory() + { + return category; + } + public void setCategory(ExcelGraphElement category) + { + this.category = category; + } + public List getValueList() + { + return valueList; + } + public void setValueList(List valueList) + { + this.valueList = valueList; + } + + public Integer getGraphType() + { + return graphType; + } + public void setGraphType(Integer graphType) + { + this.graphType = graphType; + } + public List getTitleCell() + { + return titleCell; + } + public void setTitleCell(List titleCell) + { + this.titleCell = titleCell; + } + public List getTitle() + { + return title; + } + public void setTitle(List title) + { + this.title = title; + } + + + +} diff --git a/easypoi-base/src/main/java/org/jeecgframework/poi/excel/graph/entity/ExcelGraphElement.java b/easypoi-base/src/main/java/org/jeecgframework/poi/excel/graph/entity/ExcelGraphElement.java new file mode 100644 index 0000000..2fe5f36 --- /dev/null +++ b/easypoi-base/src/main/java/org/jeecgframework/poi/excel/graph/entity/ExcelGraphElement.java @@ -0,0 +1,64 @@ +/** + * + */ +package org.jeecgframework.poi.excel.graph.entity; + +import org.jeecgframework.poi.excel.graph.constant.ExcelGraphElementType; + + +/** + * @author xfworld + * @since 2015-12-30 + * @version 1.0 + * + */ +public class ExcelGraphElement +{ + private Integer startRowNum; + private Integer endRowNum; + private Integer startColNum; + private Integer endColNum; + private Integer elementType=ExcelGraphElementType.StringType; + + + public Integer getStartRowNum() + { + return startRowNum; + } + public void setStartRowNum(Integer startRowNum) + { + this.startRowNum = startRowNum; + } + public Integer getEndRowNum() + { + return endRowNum; + } + public void setEndRowNum(Integer endRowNum) + { + this.endRowNum = endRowNum; + } + public Integer getStartColNum() + { + return startColNum; + } + public void setStartColNum(Integer startColNum) + { + this.startColNum = startColNum; + } + public Integer getEndColNum() + { + return endColNum; + } + public void setEndColNum(Integer endColNum) + { + this.endColNum = endColNum; + } + public Integer getElementType() + { + return elementType; + } + public void setElementType(Integer elementType) + { + this.elementType = elementType; + } +} diff --git a/easypoi-base/src/main/java/org/jeecgframework/poi/excel/graph/entity/ExcelTitleCell.java b/easypoi-base/src/main/java/org/jeecgframework/poi/excel/graph/entity/ExcelTitleCell.java new file mode 100644 index 0000000..8a90431 --- /dev/null +++ b/easypoi-base/src/main/java/org/jeecgframework/poi/excel/graph/entity/ExcelTitleCell.java @@ -0,0 +1,44 @@ +/** + * + */ +package org.jeecgframework.poi.excel.graph.entity; + +/** + * @author xfowrld + * @since 2015-12-30 + * @version 1.0 + * + */ +public class ExcelTitleCell +{ + private Integer row; + private Integer col; + + public ExcelTitleCell(){ + + } + + public ExcelTitleCell(Integer row,Integer col){ + this.row=row; + this.col=col; + } + + public Integer getRow() + { + return row; + } + public void setRow(Integer row) + { + this.row = row; + } + public Integer getCol() + { + return col; + } + public void setCol(Integer col) + { + this.col = col; + } + + +} diff --git a/easypoi-base/src/main/java/org/jeecgframework/poi/excel/graph/package-info.java b/easypoi-base/src/main/java/org/jeecgframework/poi/excel/graph/package-info.java new file mode 100644 index 0000000..4a10b91 --- /dev/null +++ b/easypoi-base/src/main/java/org/jeecgframework/poi/excel/graph/package-info.java @@ -0,0 +1,10 @@ +/** + * + */ +/** + * @author xfworld + * @since 2016-1-13 + * @version 1.0 + * Excel 图形构造服务 + */ +package org.jeecgframework.poi.excel.graph; \ No newline at end of file diff --git a/easypoi-base/src/main/java/org/jeecgframework/poi/util/PoiExcelGraphDataUtil.java b/easypoi-base/src/main/java/org/jeecgframework/poi/util/PoiExcelGraphDataUtil.java new file mode 100644 index 0000000..c18dc70 --- /dev/null +++ b/easypoi-base/src/main/java/org/jeecgframework/poi/util/PoiExcelGraphDataUtil.java @@ -0,0 +1,55 @@ +/** + * + */ +package org.jeecgframework.poi.util; + + + +import java.util.List; + +import org.apache.poi.ss.usermodel.Sheet; +import org.jeecgframework.poi.excel.graph.entity.ExcelGraph; +import org.jeecgframework.poi.excel.graph.entity.ExcelGraphElement; + +/** + * @author xfworld + * @since 2016-1-4 + * @version 1.0 + * 构建特殊数据结构 + */ +public class PoiExcelGraphDataUtil +{ + + /** + * 构建获取数据最后行数 并写入到定义对象中 + * @param dataSourceSheet + * @param graph + */ + public static void buildGraphData(Sheet dataSourceSheet,ExcelGraph graph){ + if(graph!=null&&graph.getCategory()!=null&&graph.getValueList()!=null&&graph.getValueList().size()>0){ + graph.getCategory().setEndRowNum(dataSourceSheet.getLastRowNum()); + for(ExcelGraphElement e:graph.getValueList()){ + if(e!=null){ + e.setEndRowNum(dataSourceSheet.getLastRowNum()); + } + } + } + } + + /** + * 构建多个图形对象 + * @param dataSourceSheet + * @param graphList + */ + public static void buildGraphData(Sheet dataSourceSheet,List graphList){ + if(graphList!=null&&graphList.size()>0){ + for(ExcelGraph graph:graphList){ + buildGraphData(dataSourceSheet,graph); + } + } + } + + + + +} diff --git a/easypoi-web/src/main/java/org/jeecgframework/poi/excel/entity/vo/MapExcelConstants.java b/easypoi-web/src/main/java/org/jeecgframework/poi/excel/entity/vo/MapExcelConstants.java index 18fed1c..3856eac 100644 --- a/easypoi-web/src/main/java/org/jeecgframework/poi/excel/entity/vo/MapExcelConstants.java +++ b/easypoi-web/src/main/java/org/jeecgframework/poi/excel/entity/vo/MapExcelConstants.java @@ -28,7 +28,7 @@ public interface MapExcelConstants extends BasePOIConstants { /** * Entity List */ - public final static String ENTITY_LIST = "data"; + public final static String ENTITY_LIST = "EntityList"; /** * 数据列表 */ diff --git a/easypoi-web/src/main/java/org/jeecgframework/poi/excel/entity/vo/MapExcelGraphConstants.java b/easypoi-web/src/main/java/org/jeecgframework/poi/excel/entity/vo/MapExcelGraphConstants.java new file mode 100644 index 0000000..7b72d14 --- /dev/null +++ b/easypoi-web/src/main/java/org/jeecgframework/poi/excel/entity/vo/MapExcelGraphConstants.java @@ -0,0 +1,19 @@ +/** + * + */ +package org.jeecgframework.poi.excel.entity.vo; + + + +/** + * @author xfworld + * @since 2015-12-31 + * @version 1.0 + * + */ +public interface MapExcelGraphConstants extends MapExcelConstants +{ + public final static String MAP_GRAPH_EXCEL_VIEW = "MapGraphExcelView"; + public final static String GRAPH_DEFINED = "graphDefined"; + +} diff --git a/easypoi-web/src/main/java/org/jeecgframework/poi/excel/view/MapGraphExcelView.java b/easypoi-web/src/main/java/org/jeecgframework/poi/excel/view/MapGraphExcelView.java new file mode 100644 index 0000000..4e17ec8 --- /dev/null +++ b/easypoi-web/src/main/java/org/jeecgframework/poi/excel/view/MapGraphExcelView.java @@ -0,0 +1,82 @@ +/** + * Copyright 2013-2015 xfworld (xfworld@gmail.com) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.jeecgframework.poi.excel.view; + +import java.util.List; +import java.util.Map; + +import javax.annotation.Resource; +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.ss.usermodel.Workbook; +import org.jeecgframework.poi.excel.ExcelExportUtil; +import org.jeecgframework.poi.excel.entity.ExportParams; +import org.jeecgframework.poi.excel.entity.params.ExcelExportEntity; +import org.jeecgframework.poi.excel.entity.vo.MapExcelGraphConstants; +import org.jeecgframework.poi.excel.graph.builder.ExcelChartBuildService; +import org.jeecgframework.poi.excel.graph.entity.ExcelGraph; +import org.jeecgframework.poi.excel.view.MiniAbstractExcelView; +import org.springframework.stereotype.Controller; + +/** + * Map 对象接口 + * + * @author xfworld + * @since 2016-01-04 + */ +@SuppressWarnings("unchecked") +@Controller(MapExcelGraphConstants.MAP_GRAPH_EXCEL_VIEW) +public class MapGraphExcelView extends MiniAbstractExcelView { + + public MapGraphExcelView() { + super(); + } + + @Override + protected void renderMergedOutputModel(Map model, HttpServletRequest request, + HttpServletResponse response) throws Exception { + String codedFileName = "临时文件"; + ExportParams params=(ExportParams)model.get(MapExcelGraphConstants.PARAMS); + List entityList=(List) model.get(MapExcelGraphConstants.ENTITY_LIST); + List> mapList=(List>)model.get(MapExcelGraphConstants.MAP_LIST); + List graphDefinedList=(List)model.get(MapExcelGraphConstants.GRAPH_DEFINED); + //构建数据 + Workbook workbook = ExcelExportUtil.exportExcel(params,entityList,mapList); + ExcelChartBuildService.createExcelChart(workbook,graphDefinedList, params.isDynamicData(), params.isAppendGraph()); + + if (model.containsKey(MapExcelGraphConstants.FILE_NAME)) { + codedFileName = (String) model.get(MapExcelGraphConstants.FILE_NAME); + } + if (workbook instanceof HSSFWorkbook) { + codedFileName += HSSF; + } else { + codedFileName += XSSF; + } + if (isIE(request)) { + codedFileName = java.net.URLEncoder.encode(codedFileName, "UTF8"); + } else { + codedFileName = new String(codedFileName.getBytes("UTF-8"), "ISO-8859-1"); + } + response.setHeader("content-disposition", "attachment;filename=" + codedFileName); + ServletOutputStream out = response.getOutputStream(); + workbook.write(out); + out.flush(); + } + +}