美文网首页Linux使用技巧分享
POI导出excel生成图表(折线图、饼图、柱状图)

POI导出excel生成图表(折线图、饼图、柱状图)

作者: 枫叶_Maple | 来源:发表于2022-01-13 16:08 被阅读0次

近期做的需求中有个统计页面,页面中要求导出统计数据时连同图表一起导出到excel中,项目中用到的是阿里的easyExcel,查阅资料后发现easyExcel中没有很好的画图表的解决方案。POI到是提供了不错的解决方案,代码如下:

  • 数据查询
/**
     * 按用户统计数据导出
     *
     * @param condition
     * @return
     */
    public ResultResponse<String> exportExcelByUser(EventAlarmStaticsCondition condition) {
        // 查询数据
        ResultResponse<List<JSONObject>> response = eventAlarmStaticsByUser(condition);
        if(response.checkFailed() || CollectionUtils.isEmpty(response.getData())){
            return ResultResponse.success("");
        }

        List<String> heads = new ArrayList<>();
        // 获取要导出的表头数据
        List<EventTypeEntity> typeList = getEventTypeEntityList();
        List<String> titles = typeList.stream().map(EventTypeEntity::getEventName).collect(Collectors.toList());
        heads.add(Constants.NAME);
        heads.add(Constants.TOTAL_EVENT);
        heads.add(Constants.AVG_TIME);
        heads.addAll(titles);

        List<JSONObject> objectList = response.getData();
        // 柱状图y轴事件总数数据
        List<Double> lineYDataList = new ArrayList<>();
        // 柱状图y轴平均处理时长数据
        List<Double> timeYDataList = new ArrayList<>();
        // 填充折线图y轴数据
        for (JSONObject jsonObject : objectList) {
            lineYDataList.add(jsonObject.getDoubleValue(Constants.TOTAL_COUNT));
            timeYDataList.add(jsonObject.getDoubleValue(Constants.TOTAL_AVG_TIME));
        }

        // 创建wb并绘制折线图、饼图、柱状图
        XSSFWorkbook wb = new XSSFWorkbook();
        XSSFSheet sheet = wb.createSheet(ExportFileConstant.eventStaticsNamePrefix);
        drawSheetTable(wb, sheet, heads, response.getData(), Constants.USER_NAME);

        // 柱状图
        ExcelUtils.createBarChart(sheet, lineYDataList, ExportFileConstant.staticsCount, 1, objectList.size(), 0, 0, 4, 30, 0, 10 );
        ExcelUtils.createBarChart(sheet, timeYDataList, ExportFileConstant.staticsEfficiency, 1, objectList.size(), 0, 0, 4, 30, 11, 22 );
        // 上传文件
        String url = upload(wb, ExportFileConstant.eventStaticsNamePrefix);
        return ResultResponse.successData(url);
    }
    
        /**
     * 上传文件
     *
     * @param wb
     * @param fileName
     * @return
     */
    private String upload (XSSFWorkbook wb, String fileName){
        String filePath = fileConfig.getCreatFilePath() + fileName + ExcelTypeEnum.XLSX.getValue();
        try {
            DownloadUtil.createFolderIfNotExists(fileConfig.getCreatFilePath());
            FileOutputStream outputStream = new FileOutputStream(filePath);
            wb.write(outputStream);
            outputStream.close();
        } catch (Exception e) {
            log.error("Failed to upload data,exception:{}", e);
            return null;
        }
        //上传到s3
        return s3Service.fileUpload(filePath, fileName + ExcelTypeEnum.XLSX.getValue(), S3Tag.shortTerm);
    }
  • 向sheet中写入数据

/**
     * sheet数据
     *
     * @param sheet
     * @param titleList
     * @param dataList
     * @return
     */
    private boolean drawSheetTable(XSSFWorkbook wb, XSSFSheet sheet, List<String> titleList, List<JSONObject> dataList, String groupType) {
        boolean result = true;

        // 设置样式以及字体样式
        XSSFCellStyle headerStyle = ExcelUtils.createHeadCellStyle(wb);
        XSSFCellStyle contentStyle = ExcelUtils.createContentCellStyle(wb);
        XSSFCellStyle intStyle = ExcelUtils.createContentNumericalCellStyle(wb,"#,##0");

        // 获取事件类型数据
        List<EventTypeEntity> typeList = getEventTypeEntityList();
        List<Integer> countList = new ArrayList<>();
        for (EventTypeEntity type : typeList) {
            String eventType = Constants.EVENT_TYPE + type.getEventType();
            int count = 0;
            for (JSONObject jsonObject : dataList) {
                count += jsonObject.getIntValue(eventType);
            }
            countList.add(count);
        }
        countList.add(dataList.stream().mapToInt(jsonObject -> jsonObject.getIntValue(Constants.TOTAL_COUNT)).sum());
        countList.add(dataList.stream().mapToInt(jsonObject -> jsonObject.getIntValue(Constants.TOTAL_AVG_TIME)).sum());

        // 根据数据创建excel第一行标题行
        XSSFRow row0 = sheet.createRow(0);
        for (int i = 0; i < titleList.size(); i++) {
            // 设置标题
            row0.createCell(i).setCellValue(titleList.get(i));
            // 设置标题行样式
            row0.getCell(i).setCellStyle(headerStyle);
        }
        // 填充数据
        String period = Constants.PERIOD.equals(groupType) ? Constants.PERIOD : Constants.USER_NAME;
        for (int k = 0; k < dataList.size(); k++) {
            // 获取每一项的数据
            JSONObject data = dataList.get(k);
            // 设置每一行的字段标题和数据
            XSSFRow row = sheet.createRow(k + 1);
            // 标题
            row.createCell(0).setCellValue(data.getString(period));
            sheet.getRow(k + 1).getCell(0).setCellStyle(contentStyle);
            row.createCell(1).setCellValue(data.getString(Constants.TOTAL_COUNT));
            sheet.getRow(k + 1).getCell(1).setCellStyle(contentStyle);
            // 处理数字过长转成科学计数法问题
            BigDecimal avgTimeDecimal = new BigDecimal(data.getString(Constants.TOTAL_AVG_TIME));
            row.createCell(2).setCellValue(avgTimeDecimal.toPlainString());
            sheet.getRow(k + 1).getCell(2).setCellStyle(contentStyle);
            // 设置左边字段样式
            for (int j = 0; j < typeList.size(); j++) {
                EventTypeEntity entity = typeList.get(j);
                String eventTYpeData = data.getString(Constants.EVENT_TYPE + entity.getEventType());
                row.createCell(j + 3).setCellValue(eventTYpeData);
                // 设置数据样式
                sheet.getRow(k + 1).getCell(j + 3).setCellStyle(intStyle);
            }
        }

        // 合计
        XSSFRow endRow = sheet.createRow(dataList.size() + 1);
        endRow.createCell(0).setCellValue(Constants.TOTAL);
        endRow.getCell(0).setCellStyle(contentStyle);
        // 事件总数
        endRow.createCell(1).setCellValue(countList.get(countList.size() - 2));
        endRow.getCell(1).setCellStyle(contentStyle);
        // 处理科学计数法问题
        BigDecimal bigDecimal = new BigDecimal(countList.get(countList.size() - 1));
        endRow.createCell(2).setCellValue(bigDecimal.toPlainString());
        endRow.getCell(2).setCellStyle(contentStyle);
        for (int i = 3; i <= countList.size(); i++) {
            endRow.createCell(i).setCellValue(countList.get(i - 3));
            endRow.getCell(i).setCellStyle(contentStyle);
        }
        return result;
    }
  • 工具类
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xddf.usermodel.PresetColor;
import org.apache.poi.xddf.usermodel.XDDFColor;
import org.apache.poi.xddf.usermodel.XDDFSolidFillProperties;
import org.apache.poi.xddf.usermodel.chart.*;
import org.apache.poi.xssf.usermodel.*;

import java.util.List;

public class ExcelUtils {
    /**
     * 创建表头样式
     * @param wb
     * @return
     */
    public static XSSFCellStyle createHeadCellStyle(XSSFWorkbook wb) {
        XSSFCellStyle cellStyle = wb.createCellStyle();
        cellStyle.setWrapText(true);// 设置自动换行
        cellStyle.setFillForegroundColor(IndexedColors.BLUE_GREY.getIndex());//背景颜色
        cellStyle.setAlignment(HorizontalAlignment.CENTER); //水平居中
        cellStyle.setVerticalAlignment(VerticalAlignment.CENTER); //垂直对齐
        cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        cellStyle.setBottomBorderColor(IndexedColors.BLACK.index);
        cellStyle.setBorderBottom(BorderStyle.THIN); //下边框
        cellStyle.setBorderLeft(BorderStyle.THIN); //左边框
        cellStyle.setBorderRight(BorderStyle.THIN); //右边框
        cellStyle.setBorderTop(BorderStyle.THIN); //上边框

        XSSFFont headerFont = wb.createFont(); // 创建字体样式
        headerFont.setBold(true); //字体加粗
        headerFont.setFontName("宋体"); // 设置字体类型
        headerFont.setFontHeightInPoints((short) 12); // 设置字体大小
        cellStyle.setFont(headerFont); // 为标题样式设置字体样式

        return cellStyle;
    }
    /**
     * 创建标题样式
     * @param wb
     * @return
     */
    public static XSSFCellStyle createTitleCellStyle(XSSFWorkbook wb) {
        XSSFCellStyle cellStyle = wb.createCellStyle();
        cellStyle.setAlignment(HorizontalAlignment.CENTER);//水平居中
        cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);//垂直对齐
        cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        cellStyle.setFillForegroundColor(IndexedColors.WHITE1.getIndex());//背景颜色

        XSSFFont headerFont1 = wb.createFont(); // 创建字体样式
        headerFont1.setBold(true); //字体加粗
        headerFont1.setFontName("宋体"); // 设置字体类型
        headerFont1.setFontHeightInPoints((short) 16); // 设置字体大小
        cellStyle.setFont(headerFont1); // 为标题样式设置字体样式

        return cellStyle;
    }
    /**
     * 创建内容样式
     * @param wb
     * @return
     */
    public static XSSFCellStyle createRemarkCellStyle(XSSFWorkbook wb) {
        XSSFCellStyle cellStyle = wb.createCellStyle();
        cellStyle.setVerticalAlignment(VerticalAlignment.JUSTIFY);// 两边对齐
        cellStyle.setAlignment(HorizontalAlignment.LEFT);// 居左
        cellStyle.setWrapText(true);// 设置自动换行
        cellStyle.setBorderBottom(BorderStyle.THIN); //下边框
        cellStyle.setBorderLeft(BorderStyle.THIN); //左边框
        cellStyle.setBorderRight(BorderStyle.THIN); //右边框
        cellStyle.setBorderTop(BorderStyle.THIN); //上边框

        // 生成12号字体
        XSSFFont font = wb.createFont();
        font.setColor((short)8);
        font.setFontHeightInPoints((short) 12);
        cellStyle.setFont(font);

        return cellStyle;
    }
    /**
     * 创建内容样式
     * @param wb
     * @return
     */
    public static XSSFCellStyle createContentCellStyle(XSSFWorkbook wb) {
        XSSFCellStyle cellStyle = wb.createCellStyle();
        cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);// 垂直居中
        cellStyle.setAlignment(HorizontalAlignment.CENTER);// 水平居中
        cellStyle.setWrapText(true);// 设置自动换行
        cellStyle.setBorderBottom(BorderStyle.THIN); //下边框
        cellStyle.setBorderLeft(BorderStyle.THIN); //左边框
        cellStyle.setBorderRight(BorderStyle.THIN); //右边框
        cellStyle.setBorderTop(BorderStyle.THIN); //上边框

        // 生成12号字体
        XSSFFont font = wb.createFont();
        font.setColor((short)8);
        font.setFontHeightInPoints((short) 12);
        cellStyle.setFont(font);

        return cellStyle;
    }
    /**
     * 创建内容样式
     * @param wb
     * @return
     */
    public static XSSFCellStyle createContentNumericalCellStyle(XSSFWorkbook wb,String format) {
        XSSFCellStyle cellStyle = wb.createCellStyle();
        XSSFDataFormat dataFormat = wb.createDataFormat();
        cellStyle.setDataFormat(dataFormat.getFormat(format));
        cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);// 垂直居中
        cellStyle.setAlignment(HorizontalAlignment.CENTER);// 水平居中
        cellStyle.setWrapText(true);// 设置自动换行
        cellStyle.setBorderBottom(BorderStyle.THIN); //下边框
        cellStyle.setBorderLeft(BorderStyle.THIN); //左边框
        cellStyle.setBorderRight(BorderStyle.THIN); //右边框
        cellStyle.setBorderTop(BorderStyle.THIN); //上边框

        // 生成12号字体
        XSSFFont font = wb.createFont();
        font.setColor((short)8);
        font.setFontHeightInPoints((short) 12);
        cellStyle.setFont(font);

        return cellStyle;
    }

    /**
     * 折线图
     *
     * @param sheet sheet
     * @param chartTitle 折线图标题
     * @param lineName 折线名称
     * @param xName x轴名称
     * @param yName y轴名称
     * @param firstRow 开始行
     * @param dataEndRow 结束行
     * @param startCol 开始列
     * @param xAxisCol x轴列
     * @param valueCol y轴列
     */
    public static void createSheetLineChark(XSSFSheet sheet, String chartTitle,String lineName,String xName,String yName, int firstRow, int dataEndRow, int startCol, int xAxisCol, int valueCol) {
        //创建一个画布
        XSSFDrawing drawing = sheet.createDrawingPatriarch();
        //前四个默认0,[0,4]:从0列4行开始;[7,20]:宽度7个单元格,20向下扩展到20行
        //默认宽度(14-8)*12
        XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, startCol, dataEndRow + 4, startCol + 9, dataEndRow + 28);
        //创建一个chart对象
        XSSFChart chart = drawing.createChart(anchor);
        //标题
        chart.setTitleText(chartTitle);
        //标题是否覆盖图表
        chart.setTitleOverlay(false);
        //图例位置
//        XDDFChartLegend legend = chart.getOrAddLegend();
//        legend.setPosition(LegendPosition.TOP);
        //分类轴标(X轴),标题位置
        XDDFCategoryAxis bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
        if(StringUtils.isNotBlank(xName))
        bottomAxis.setTitle(xName);
        //值(Y轴)轴,标题位置
        XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.LEFT);
        if(StringUtils.isNotBlank(yName))
        leftAxis.setTitle(yName);
        //CellRangeAddress(起始行号,终止行号, 起始列号,终止列号)
        //分类轴标(X轴)数据,单元格范围位置[0, 0]到[0, 6]
        XDDFDataSource<String> xData = XDDFDataSourcesFactory.fromStringCellRange(sheet, new CellRangeAddress(firstRow, dataEndRow, xAxisCol, xAxisCol));

        //数据1,单元格范围位置[1, 0]到[1, 6]
        XDDFNumericalDataSource<Double> values = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(firstRow, dataEndRow, valueCol, valueCol));

        //LINE:折线图,
        XDDFLineChartData data = (XDDFLineChartData) chart.createData(ChartTypes.LINE, bottomAxis, leftAxis);
        //图表加载数据,折线1
        XDDFLineChartData.Series series1 = (XDDFLineChartData.Series) data.addSeries(xData, values);
        //折线图例标题
        if(StringUtils.isNotBlank(lineName))
            series1.setTitle(lineName, null);
        //直线
        series1.setSmooth(false);
        //设置标记大小
        series1.setMarkerSize((short) 6);

        //设置标记样式 无
        series1.setMarkerStyle(MarkerStyle.CIRCLE);
//        series1.setShowLeaderLines(false);

        //绘制
        chart.plot(data);
    }

    /**
     * 饼图
     *
     * @param sheet sheet
     * @param chartTitle 标题
     * @param firstRow  开始行
     * @param dataEndRow 结束行
     * @param startCol 开始列
     * @param xAxisCol x轴列
     * @param valueCol 结束列
     */
    public static void createSheetPieChark(XSSFSheet sheet,String chartTitle,int firstRow,int dataEndRow,int startCol,int xAxisCol,int valueCol){
        //创建一个画布
        XSSFDrawing drawing = sheet.createDrawingPatriarch();
        //前四个默认0,[0,4]:从0列4行开始;[7,20]:宽度7个单元格,20向下扩展到20行
        //默认宽度(14-8)*12
        XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, startCol, dataEndRow + 4, startCol + 20, dataEndRow + 40);
        //创建一个chart对象
        XSSFChart chart = drawing.createChart(anchor);
        //标题
        chart.setTitleText(chartTitle);
        //标题是否覆盖图表
        chart.setTitleOverlay(false);
        //图例位置
        XDDFChartLegend legend = chart.getOrAddLegend();
        legend.setPosition(LegendPosition.TOP_RIGHT);
        //CellRangeAddress(起始行号,终止行号, 起始列号,终止列号)
        //分类轴标数据,
        XDDFDataSource<String> xData = XDDFDataSourcesFactory.fromStringCellRange(sheet, new CellRangeAddress(firstRow, dataEndRow, xAxisCol, xAxisCol));
        //数据1,单元格范围位置[1, 0]到[1, 6]
        XDDFNumericalDataSource<Double> values = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(firstRow, dataEndRow, valueCol, valueCol));
        //XDDFChartData data = chart.createData(ChartTypes.PIE3D, null, null);
        XDDFChartData data = chart.createData(ChartTypes.PIE, null, null);
        //设置为可变颜色
        data.setVaryColors(true);
        //图表加载数据
        data.addSeries(xData, values);

        //绘制
        chart.plot(data);

    }

    /**
     * 柱状图
     *
     * @param sheet
     * @param chartTitle
     * @param firstRow
     * @param dataEndRow
     * @param startCol
     * @param xAxisCol
     * @param valueCol
     */
    public static void createSheetBarChark(XSSFSheet sheet,String chartTitle,int firstRow,int dataEndRow,int startCol,int xAxisCol,int valueCol){
        //创建一个画布
        XSSFDrawing drawing = sheet.createDrawingPatriarch();
        //前四个默认0,[0,4]:从0列4行开始;[7,20]:宽度7个单元格,20向下扩展到20行
        //默认宽度(14-8)*12
        XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, startCol, dataEndRow + 4, startCol + 20, dataEndRow + 45);
        //创建一个chart对象
        XSSFChart chart = drawing.createChart(anchor);
        //标题
        chart.setTitleText(chartTitle);
        //标题是否覆盖图表
        chart.setTitleOverlay(false);

        //图例位置
//        XDDFChartLegend legend = chart.getOrAddLegend();
//        legend.setPosition(LegendPosition.TOP);
        //分类轴标(X轴),标题位置
        XDDFCategoryAxis bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
        //值(Y轴)轴,标题位置
        XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.LEFT);
        //CellRangeAddress(起始行号,终止行号, 起始列号,终止列号)
        //分类轴标数据,
        XDDFDataSource<String> xData = XDDFDataSourcesFactory.fromStringCellRange(sheet, new CellRangeAddress(firstRow, dataEndRow, xAxisCol, xAxisCol));

        //数据1,单元格范围位置[1, 0]到[1, 6]
        XDDFNumericalDataSource<Double> values = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(firstRow, dataEndRow, valueCol, valueCol));
        //bar:条形图,
        XDDFBarChartData bar = (XDDFBarChartData) chart.createData(ChartTypes.BAR, bottomAxis, leftAxis);

        leftAxis.setCrossBetween(AxisCrossBetween.BETWEEN);
        //设置为可变颜色
        bar.setVaryColors(true);
        //条形图方向,纵向/横向:纵向
        bar.setBarDirection(BarDirection.COL);

        //图表加载数据,条形图1
        XDDFBarChartData.Series series1 = (XDDFBarChartData.Series) bar.addSeries(xData, values);
        //条形图例标题

        XDDFSolidFillProperties fill = new XDDFSolidFillProperties(XDDFColor.from(PresetColor.BLUE));
        //条形图,填充颜色
        series1.setFillProperties(fill);
        //绘制
        chart.plot(bar);
    }

    /**
     * 创建画布
     *
     * @param sheet
     * @param chartTitle
     * @param dataEndRow
     * @param startCol
     * @return
     */
    public static XSSFChart createSheetDrawing(XSSFSheet sheet, String chartTitle, int dataEndRow, int startCol) {
        //创建一个画布
        XSSFDrawing drawing = sheet.createDrawingPatriarch();
        //前四个默认0,[0,4]:从0列4行开始;[7,20]:宽度7个单元格,20向下扩展到20行
        //默认宽度(14-8)*12
        XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, startCol, dataEndRow + 4, startCol + 9, dataEndRow + 28);
        //创建一个chart对象
        XSSFChart chart = drawing.createChart(anchor);
        //标题
        chart.setTitleText(chartTitle);
        //标题是否覆盖图表
        chart.setTitleOverlay(false);
        return chart;
    }


    /**
     * 创建折线图
     *
     * @param sheet
     * @param yDataList y轴数据
     * @param title
     * @param firstRow
     * @param endRow
     * @param startCol
     * @param endCol
     */
    public static void createLineChart(XSSFSheet sheet, List<Double> yDataList, String title, int firstRow, int endRow, int startCol, int endCol, int firstRowOffset, int endRowOffset, int startColOffset, int endColOffset) {

        //创建一个画布
        XSSFChart chart = getSheetDrawing(sheet, title, startCol, firstRowOffset, endRowOffset, startColOffset, endColOffset);

        //图例位置
        XDDFChartLegend legend = chart.getOrAddLegend();
        legend.setPosition(LegendPosition.TOP);
        //分类轴标(X轴),标题位置
        XDDFCategoryAxis bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
        //值(Y轴)轴,标题位置
        XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.LEFT);
        //LINE:折线图,
        XDDFLineChartData data = (XDDFLineChartData) chart.createData(ChartTypes.LINE, bottomAxis, leftAxis);

        // X轴数据
        XDDFCategoryDataSource countries = XDDFDataSourcesFactory.fromStringCellRange(sheet, new CellRangeAddress(firstRow, endRow, startCol, endCol));
        Double[] doubles = new Double[yDataList.size()];
        for (int i= 0; i< yDataList.size(); i++) {
            doubles[i] = yDataList.get(i);
        }
        // Y轴数据
        XDDFNumericalDataSource<Double> source = XDDFDataSourcesFactory.fromArray(doubles);

        XDDFLineChartData.Series series = (XDDFLineChartData.Series) data.addSeries(countries, source);
        series.setTitle(title, null);
        //直线
        series.setSmooth(false);
        //设置标记大小
        series.setMarkerSize((short) 6);

        //绘制
        chart.plot(data);
    }

    /**
     * 饼图
     *
     * @param sheet sheet
     * @param chartTitle 标题
     * @param firstRow  开始行
     * @param endRow 结束行
     * @param startCol 开始列
     * @param endCol 结束列
     * @param firstRowOffset  饼图开始y坐标偏移量
     * @param endRowOffset    饼图结束y坐标偏移量
     * @param startColOffset  饼图开始x坐标偏移量
     * @param endColOffset    饼图结束x坐标偏移量
     */
    public static void createPieChart(XSSFSheet sheet, List<Double> yDataList, String chartTitle, int firstRow, int endRow, int startCol, int endCol, int firstRowOffset, int endRowOffset, int startColOffset, int endColOffset) {
        //创建一个画布
        XSSFChart chart = getSheetDrawing(sheet, chartTitle, startCol, firstRowOffset, endRowOffset, startColOffset, endColOffset);
        //图例位置
        XDDFChartLegend legend = chart.getOrAddLegend();
        legend.setPosition(LegendPosition.TOP_RIGHT);
        //CellRangeAddress(起始行号,终止行号, 起始列号,终止列号)
        //分类轴标数据,
        XDDFDataSource<String> xData = XDDFDataSourcesFactory.fromStringCellRange(sheet, new CellRangeAddress(firstRow, endRow, startCol, endCol));

        Double[] doubles = new Double[yDataList.size()];
        for (int i= 0; i< yDataList.size(); i++) {
            doubles[i] = yDataList.get(i);
        }
        // Y轴数据
        XDDFNumericalDataSource<Double> values = XDDFDataSourcesFactory.fromArray(doubles);
        XDDFChartData data = chart.createData(ChartTypes.PIE, null, null);
        //设置为可变颜色
        data.setVaryColors(true);
        //图表加载数据
        data.addSeries(xData, values);

        //绘制
        chart.plot(data);

    }

    /**
     * 柱状图
     *
     * @param sheet
     * @param yDataList
     * @param chartTitle
     * @param firstRow
     * @param endRow
     * @param startCol
     * @param endCol
     * @param firstRowOffset
     * @param endRowOffset
     * @param startColOffset
     * @param endColOffset
     */
    public static void createBarChart(XSSFSheet sheet, List<Double> yDataList, String chartTitle, int firstRow, int endRow, int startCol, int endCol, int firstRowOffset, int endRowOffset, int startColOffset, int endColOffset) {
        // 获取画布
        XSSFChart chart = getSheetDrawing(sheet, chartTitle, startCol, firstRowOffset, endRowOffset, startColOffset, endColOffset);
        //获取或添加图例
        XDDFChartLegend legend = chart.getOrAddLegend();
        //设置图例的位置
        legend.setPosition(LegendPosition.BOTTOM);
        //创建 类别轴 放置底部
        XDDFCategoryAxis bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
        //创建数据轴 放置左侧
        XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.LEFT);
//        leftAxis.setTitle(chartTitle);
        //创建数据中心  0,0
        XDDFCategoryDataSource xs = XDDFDataSourcesFactory.fromStringCellRange(sheet, new CellRangeAddress(firstRow, endRow, startCol, endCol));

        Double[] doubles = new Double[yDataList.size()];
        for (int i= 0; i< yDataList.size(); i++) {
            doubles[i] = yDataList.get(i);
        }
        XDDFNumericalDataSource<Double> xv = XDDFDataSourcesFactory.fromArray(doubles);
        //数据加载
        XDDFChartData data = chart.createData(ChartTypes.BAR, bottomAxis, leftAxis);
        XDDFChartData.Series series = data.addSeries(xs, xv);
        series.setTitle(chartTitle, null);
        XDDFBarChartData bar = (XDDFBarChartData) data;
        bar.setVaryColors(true);
        bar.setBarDirection(BarDirection.COL);
        bar.setBarGrouping(BarGrouping.STACKED);
        chart.plot(data);
    }

    /**
     * 创建画布
     *
     * @param sheet
     * @param chartTitle
     * @param startCol
     * @param firstRowOffset
     * @param endRowOffset
     * @param startColOffset
     * @param endColOffset
     * @return
     */
    private static XSSFChart getSheetDrawing(XSSFSheet sheet, String chartTitle, int startCol, int firstRowOffset, int endRowOffset, int startColOffset, int endColOffset) {
        //创建一个画布
        XSSFDrawing drawing = sheet.createDrawingPatriarch();
        //前四个默认0,[0,4]:从0列4行开始;[7,20]:宽度7个单元格,20向下扩展到20行

        //默认宽度(14-8)*12
        int lastRowNum = sheet.getLastRowNum();
        XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, startCol + startColOffset, lastRowNum + firstRowOffset, startCol + endColOffset, lastRowNum + endRowOffset);
        //创建一个chart对象
        XSSFChart chart = drawing.createChart(anchor);
        //标题
        chart.setTitleText(chartTitle);
        //标题是否覆盖图表
        chart.setTitleOverlay(false);
        return chart;
    }

}

图片 图片 图片 图片
  • 参考链接
https://www.freesion.com/article/3914537989/

相关文章

网友评论

    本文标题:POI导出excel生成图表(折线图、饼图、柱状图)

    本文链接:https://www.haomeiwen.com/subject/fewncrtx.html