POI導(dǎo)出excel生成圖表(折線圖偎巢、餅圖蔼夜、柱狀圖)

近期做的需求中有個(gè)統(tǒng)計(jì)頁(yè)面,頁(yè)面中要求導(dǎo)出統(tǒng)計(jì)數(shù)據(jù)時(shí)連同圖表一起導(dǎo)出到excel中压昼,項(xiàng)目中用到的是阿里的easyExcel求冷,查閱資料后發(fā)現(xiàn)easyExcel中沒(méi)有很好的畫(huà)圖表的解決方案。POI到是提供了不錯(cuò)的解決方案窍霞,代碼如下:

  • 數(shù)據(jù)查詢
/**
     * 按用戶統(tǒng)計(jì)數(shù)據(jù)導(dǎo)出
     *
     * @param condition
     * @return
     */
    public ResultResponse<String> exportExcelByUser(EventAlarmStaticsCondition condition) {
        // 查詢數(shù)據(jù)
        ResultResponse<List<JSONObject>> response = eventAlarmStaticsByUser(condition);
        if(response.checkFailed() || CollectionUtils.isEmpty(response.getData())){
            return ResultResponse.success("");
        }

        List<String> heads = new ArrayList<>();
        // 獲取要導(dǎo)出的表頭數(shù)據(jù)
        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軸事件總數(shù)數(shù)據(jù)
        List<Double> lineYDataList = new ArrayList<>();
        // 柱狀圖y軸平均處理時(shí)長(zhǎng)數(shù)據(jù)
        List<Double> timeYDataList = new ArrayList<>();
        // 填充折線圖y軸數(shù)據(jù)
        for (JSONObject jsonObject : objectList) {
            lineYDataList.add(jsonObject.getDoubleValue(Constants.TOTAL_COUNT));
            timeYDataList.add(jsonObject.getDoubleValue(Constants.TOTAL_AVG_TIME));
        }

        // 創(chuàng)建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中寫(xiě)入數(shù)據(jù)

/**
     * sheet數(shù)據(jù)
     *
     * @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;

        // 設(shè)置樣式以及字體樣式
        XSSFCellStyle headerStyle = ExcelUtils.createHeadCellStyle(wb);
        XSSFCellStyle contentStyle = ExcelUtils.createContentCellStyle(wb);
        XSSFCellStyle intStyle = ExcelUtils.createContentNumericalCellStyle(wb,"#,##0");

        // 獲取事件類(lèi)型數(shù)據(jù)
        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());

        // 根據(jù)數(shù)據(jù)創(chuàng)建excel第一行標(biāo)題行
        XSSFRow row0 = sheet.createRow(0);
        for (int i = 0; i < titleList.size(); i++) {
            // 設(shè)置標(biāo)題
            row0.createCell(i).setCellValue(titleList.get(i));
            // 設(shè)置標(biāo)題行樣式
            row0.getCell(i).setCellStyle(headerStyle);
        }
        // 填充數(shù)據(jù)
        String period = Constants.PERIOD.equals(groupType) ? Constants.PERIOD : Constants.USER_NAME;
        for (int k = 0; k < dataList.size(); k++) {
            // 獲取每一項(xiàng)的數(shù)據(jù)
            JSONObject data = dataList.get(k);
            // 設(shè)置每一行的字段標(biāo)題和數(shù)據(jù)
            XSSFRow row = sheet.createRow(k + 1);
            // 標(biāo)題
            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);
            // 處理數(shù)字過(guò)長(zhǎng)轉(zhuǎn)成科學(xué)計(jì)數(shù)法問(wèn)題
            BigDecimal avgTimeDecimal = new BigDecimal(data.getString(Constants.TOTAL_AVG_TIME));
            row.createCell(2).setCellValue(avgTimeDecimal.toPlainString());
            sheet.getRow(k + 1).getCell(2).setCellStyle(contentStyle);
            // 設(shè)置左邊字段樣式
            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);
                // 設(shè)置數(shù)據(jù)樣式
                sheet.getRow(k + 1).getCell(j + 3).setCellStyle(intStyle);
            }
        }

        // 合計(jì)
        XSSFRow endRow = sheet.createRow(dataList.size() + 1);
        endRow.createCell(0).setCellValue(Constants.TOTAL);
        endRow.getCell(0).setCellStyle(contentStyle);
        // 事件總數(shù)
        endRow.createCell(1).setCellValue(countList.get(countList.size() - 2));
        endRow.getCell(1).setCellStyle(contentStyle);
        // 處理科學(xué)計(jì)數(shù)法問(wèn)題
        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;
    }
  • 工具類(lèi)
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 {
    /**
     * 創(chuàng)建表頭樣式
     * @param wb
     * @return
     */
    public static XSSFCellStyle createHeadCellStyle(XSSFWorkbook wb) {
        XSSFCellStyle cellStyle = wb.createCellStyle();
        cellStyle.setWrapText(true);// 設(shè)置自動(dòng)換行
        cellStyle.setFillForegroundColor(IndexedColors.BLUE_GREY.getIndex());//背景顏色
        cellStyle.setAlignment(HorizontalAlignment.CENTER); //水平居中
        cellStyle.setVerticalAlignment(VerticalAlignment.CENTER); //垂直對(duì)齊
        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(); // 創(chuàng)建字體樣式
        headerFont.setBold(true); //字體加粗
        headerFont.setFontName("宋體"); // 設(shè)置字體類(lèi)型
        headerFont.setFontHeightInPoints((short) 12); // 設(shè)置字體大小
        cellStyle.setFont(headerFont); // 為標(biāo)題樣式設(shè)置字體樣式

        return cellStyle;
    }
    /**
     * 創(chuàng)建標(biāo)題樣式
     * @param wb
     * @return
     */
    public static XSSFCellStyle createTitleCellStyle(XSSFWorkbook wb) {
        XSSFCellStyle cellStyle = wb.createCellStyle();
        cellStyle.setAlignment(HorizontalAlignment.CENTER);//水平居中
        cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);//垂直對(duì)齊
        cellStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        cellStyle.setFillForegroundColor(IndexedColors.WHITE1.getIndex());//背景顏色

        XSSFFont headerFont1 = wb.createFont(); // 創(chuàng)建字體樣式
        headerFont1.setBold(true); //字體加粗
        headerFont1.setFontName("宋體"); // 設(shè)置字體類(lèi)型
        headerFont1.setFontHeightInPoints((short) 16); // 設(shè)置字體大小
        cellStyle.setFont(headerFont1); // 為標(biāo)題樣式設(shè)置字體樣式

        return cellStyle;
    }
    /**
     * 創(chuàng)建內(nèi)容樣式
     * @param wb
     * @return
     */
    public static XSSFCellStyle createRemarkCellStyle(XSSFWorkbook wb) {
        XSSFCellStyle cellStyle = wb.createCellStyle();
        cellStyle.setVerticalAlignment(VerticalAlignment.JUSTIFY);// 兩邊對(duì)齊
        cellStyle.setAlignment(HorizontalAlignment.LEFT);// 居左
        cellStyle.setWrapText(true);// 設(shè)置自動(dòng)換行
        cellStyle.setBorderBottom(BorderStyle.THIN); //下邊框
        cellStyle.setBorderLeft(BorderStyle.THIN); //左邊框
        cellStyle.setBorderRight(BorderStyle.THIN); //右邊框
        cellStyle.setBorderTop(BorderStyle.THIN); //上邊框

        // 生成12號(hào)字體
        XSSFFont font = wb.createFont();
        font.setColor((short)8);
        font.setFontHeightInPoints((short) 12);
        cellStyle.setFont(font);

        return cellStyle;
    }
    /**
     * 創(chuàng)建內(nèi)容樣式
     * @param wb
     * @return
     */
    public static XSSFCellStyle createContentCellStyle(XSSFWorkbook wb) {
        XSSFCellStyle cellStyle = wb.createCellStyle();
        cellStyle.setVerticalAlignment(VerticalAlignment.CENTER);// 垂直居中
        cellStyle.setAlignment(HorizontalAlignment.CENTER);// 水平居中
        cellStyle.setWrapText(true);// 設(shè)置自動(dòng)換行
        cellStyle.setBorderBottom(BorderStyle.THIN); //下邊框
        cellStyle.setBorderLeft(BorderStyle.THIN); //左邊框
        cellStyle.setBorderRight(BorderStyle.THIN); //右邊框
        cellStyle.setBorderTop(BorderStyle.THIN); //上邊框

        // 生成12號(hào)字體
        XSSFFont font = wb.createFont();
        font.setColor((short)8);
        font.setFontHeightInPoints((short) 12);
        cellStyle.setFont(font);

        return cellStyle;
    }
    /**
     * 創(chuàng)建內(nèi)容樣式
     * @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);// 設(shè)置自動(dòng)換行
        cellStyle.setBorderBottom(BorderStyle.THIN); //下邊框
        cellStyle.setBorderLeft(BorderStyle.THIN); //左邊框
        cellStyle.setBorderRight(BorderStyle.THIN); //右邊框
        cellStyle.setBorderTop(BorderStyle.THIN); //上邊框

        // 生成12號(hào)字體
        XSSFFont font = wb.createFont();
        font.setColor((short)8);
        font.setFontHeightInPoints((short) 12);
        cellStyle.setFont(font);

        return cellStyle;
    }

    /**
     * 折線圖
     *
     * @param sheet sheet
     * @param chartTitle 折線圖標(biāo)題
     * @param lineName 折線名稱(chēng)
     * @param xName x軸名稱(chēng)
     * @param yName y軸名稱(chēng)
     * @param firstRow 開(kāi)始行
     * @param dataEndRow 結(jié)束行
     * @param startCol 開(kāi)始列
     * @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) {
        //創(chuàng)建一個(gè)畫(huà)布
        XSSFDrawing drawing = sheet.createDrawingPatriarch();
        //前四個(gè)默認(rèn)0韭山,[0,4]:從0列4行開(kāi)始;[7,20]:寬度7個(gè)單元格,20向下擴(kuò)展到20行
        //默認(rèn)寬度(14-8)*12
        XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, startCol, dataEndRow + 4, startCol + 9, dataEndRow + 28);
        //創(chuàng)建一個(gè)chart對(duì)象
        XSSFChart chart = drawing.createChart(anchor);
        //標(biāo)題
        chart.setTitleText(chartTitle);
        //標(biāo)題是否覆蓋圖表
        chart.setTitleOverlay(false);
        //圖例位置
//        XDDFChartLegend legend = chart.getOrAddLegend();
//        legend.setPosition(LegendPosition.TOP);
        //分類(lèi)軸標(biāo)(X軸),標(biāo)題位置
        XDDFCategoryAxis bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
        if(StringUtils.isNotBlank(xName))
        bottomAxis.setTitle(xName);
        //值(Y軸)軸,標(biāo)題位置
        XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.LEFT);
        if(StringUtils.isNotBlank(yName))
        leftAxis.setTitle(yName);
        //CellRangeAddress(起始行號(hào)冷溃,終止行號(hào)钱磅, 起始列號(hào),終止列號(hào))
        //分類(lèi)軸標(biāo)(X軸)數(shù)據(jù)似枕,單元格范圍位置[0, 0]到[0, 6]
        XDDFDataSource<String> xData = XDDFDataSourcesFactory.fromStringCellRange(sheet, new CellRangeAddress(firstRow, dataEndRow, xAxisCol, xAxisCol));

        //數(shù)據(jù)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);
        //圖表加載數(shù)據(jù)菠净,折線1
        XDDFLineChartData.Series series1 = (XDDFLineChartData.Series) data.addSeries(xData, values);
        //折線圖例標(biāo)題
        if(StringUtils.isNotBlank(lineName))
            series1.setTitle(lineName, null);
        //直線
        series1.setSmooth(false);
        //設(shè)置標(biāo)記大小
        series1.setMarkerSize((short) 6);

        //設(shè)置標(biāo)記樣式 無(wú)
        series1.setMarkerStyle(MarkerStyle.CIRCLE);
//        series1.setShowLeaderLines(false);

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

    /**
     * 餅圖
     *
     * @param sheet sheet
     * @param chartTitle 標(biāo)題
     * @param firstRow  開(kāi)始行
     * @param dataEndRow 結(jié)束行
     * @param startCol 開(kāi)始列
     * @param xAxisCol x軸列
     * @param valueCol 結(jié)束列
     */
    public static void createSheetPieChark(XSSFSheet sheet,String chartTitle,int firstRow,int dataEndRow,int startCol,int xAxisCol,int valueCol){
        //創(chuàng)建一個(gè)畫(huà)布
        XSSFDrawing drawing = sheet.createDrawingPatriarch();
        //前四個(gè)默認(rèn)0禁舷,[0,4]:從0列4行開(kāi)始;[7,20]:寬度7個(gè)單元格,20向下擴(kuò)展到20行
        //默認(rèn)寬度(14-8)*12
        XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, startCol, dataEndRow + 4, startCol + 20, dataEndRow + 40);
        //創(chuàng)建一個(gè)chart對(duì)象
        XSSFChart chart = drawing.createChart(anchor);
        //標(biāo)題
        chart.setTitleText(chartTitle);
        //標(biāo)題是否覆蓋圖表
        chart.setTitleOverlay(false);
        //圖例位置
        XDDFChartLegend legend = chart.getOrAddLegend();
        legend.setPosition(LegendPosition.TOP_RIGHT);
        //CellRangeAddress(起始行號(hào)毅往,終止行號(hào)牵咙, 起始列號(hào),終止列號(hào))
        //分類(lèi)軸標(biāo)數(shù)據(jù)攀唯,
        XDDFDataSource<String> xData = XDDFDataSourcesFactory.fromStringCellRange(sheet, new CellRangeAddress(firstRow, dataEndRow, xAxisCol, xAxisCol));
        //數(shù)據(jù)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);
        //設(shè)置為可變顏色
        data.setVaryColors(true);
        //圖表加載數(shù)據(jù)
        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){
        //創(chuàng)建一個(gè)畫(huà)布
        XSSFDrawing drawing = sheet.createDrawingPatriarch();
        //前四個(gè)默認(rèn)0,[0,4]:從0列4行開(kāi)始;[7,20]:寬度7個(gè)單元格侯嘀,20向下擴(kuò)展到20行
        //默認(rèn)寬度(14-8)*12
        XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, startCol, dataEndRow + 4, startCol + 20, dataEndRow + 45);
        //創(chuàng)建一個(gè)chart對(duì)象
        XSSFChart chart = drawing.createChart(anchor);
        //標(biāo)題
        chart.setTitleText(chartTitle);
        //標(biāo)題是否覆蓋圖表
        chart.setTitleOverlay(false);

        //圖例位置
//        XDDFChartLegend legend = chart.getOrAddLegend();
//        legend.setPosition(LegendPosition.TOP);
        //分類(lèi)軸標(biāo)(X軸),標(biāo)題位置
        XDDFCategoryAxis bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
        //值(Y軸)軸,標(biāo)題位置
        XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.LEFT);
        //CellRangeAddress(起始行號(hào)另凌,終止行號(hào), 起始列號(hào)戒幔,終止列號(hào))
        //分類(lèi)軸標(biāo)數(shù)據(jù)吠谢,
        XDDFDataSource<String> xData = XDDFDataSourcesFactory.fromStringCellRange(sheet, new CellRangeAddress(firstRow, dataEndRow, xAxisCol, xAxisCol));

        //數(shù)據(jù)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);
        //設(shè)置為可變顏色
        bar.setVaryColors(true);
        //條形圖方向工坊,縱向/橫向:縱向
        bar.setBarDirection(BarDirection.COL);

        //圖表加載數(shù)據(jù),條形圖1
        XDDFBarChartData.Series series1 = (XDDFBarChartData.Series) bar.addSeries(xData, values);
        //條形圖例標(biāo)題

        XDDFSolidFillProperties fill = new XDDFSolidFillProperties(XDDFColor.from(PresetColor.BLUE));
        //條形圖,填充顏色
        series1.setFillProperties(fill);
        //繪制
        chart.plot(bar);
    }

    /**
     * 創(chuàng)建畫(huà)布
     *
     * @param sheet
     * @param chartTitle
     * @param dataEndRow
     * @param startCol
     * @return
     */
    public static XSSFChart createSheetDrawing(XSSFSheet sheet, String chartTitle, int dataEndRow, int startCol) {
        //創(chuàng)建一個(gè)畫(huà)布
        XSSFDrawing drawing = sheet.createDrawingPatriarch();
        //前四個(gè)默認(rèn)0王污,[0,4]:從0列4行開(kāi)始;[7,20]:寬度7個(gè)單元格罢吃,20向下擴(kuò)展到20行
        //默認(rèn)寬度(14-8)*12
        XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, startCol, dataEndRow + 4, startCol + 9, dataEndRow + 28);
        //創(chuàng)建一個(gè)chart對(duì)象
        XSSFChart chart = drawing.createChart(anchor);
        //標(biāo)題
        chart.setTitleText(chartTitle);
        //標(biāo)題是否覆蓋圖表
        chart.setTitleOverlay(false);
        return chart;
    }


    /**
     * 創(chuàng)建折線圖
     *
     * @param sheet
     * @param yDataList y軸數(shù)據(jù)
     * @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) {

        //創(chuàng)建一個(gè)畫(huà)布
        XSSFChart chart = getSheetDrawing(sheet, title, startCol, firstRowOffset, endRowOffset, startColOffset, endColOffset);

        //圖例位置
        XDDFChartLegend legend = chart.getOrAddLegend();
        legend.setPosition(LegendPosition.TOP);
        //分類(lèi)軸標(biāo)(X軸),標(biāo)題位置
        XDDFCategoryAxis bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
        //值(Y軸)軸,標(biāo)題位置
        XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.LEFT);
        //LINE:折線圖,
        XDDFLineChartData data = (XDDFLineChartData) chart.createData(ChartTypes.LINE, bottomAxis, leftAxis);

        // X軸數(shù)據(jù)
        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軸數(shù)據(jù)
        XDDFNumericalDataSource<Double> source = XDDFDataSourcesFactory.fromArray(doubles);

        XDDFLineChartData.Series series = (XDDFLineChartData.Series) data.addSeries(countries, source);
        series.setTitle(title, null);
        //直線
        series.setSmooth(false);
        //設(shè)置標(biāo)記大小
        series.setMarkerSize((short) 6);

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

    /**
     * 餅圖
     *
     * @param sheet sheet
     * @param chartTitle 標(biāo)題
     * @param firstRow  開(kāi)始行
     * @param endRow 結(jié)束行
     * @param startCol 開(kāi)始列
     * @param endCol 結(jié)束列
     * @param firstRowOffset  餅圖開(kāi)始y坐標(biāo)偏移量
     * @param endRowOffset    餅圖結(jié)束y坐標(biāo)偏移量
     * @param startColOffset  餅圖開(kāi)始x坐標(biāo)偏移量
     * @param endColOffset    餅圖結(jié)束x坐標(biāo)偏移量
     */
    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) {
        //創(chuàng)建一個(gè)畫(huà)布
        XSSFChart chart = getSheetDrawing(sheet, chartTitle, startCol, firstRowOffset, endRowOffset, startColOffset, endColOffset);
        //圖例位置
        XDDFChartLegend legend = chart.getOrAddLegend();
        legend.setPosition(LegendPosition.TOP_RIGHT);
        //CellRangeAddress(起始行號(hào)昭齐,終止行號(hào)尿招, 起始列號(hào),終止列號(hào))
        //分類(lèi)軸標(biāo)數(shù)據(jù)阱驾,
        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軸數(shù)據(jù)
        XDDFNumericalDataSource<Double> values = XDDFDataSourcesFactory.fromArray(doubles);
        XDDFChartData data = chart.createData(ChartTypes.PIE, null, null);
        //設(shè)置為可變顏色
        data.setVaryColors(true);
        //圖表加載數(shù)據(jù)
        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) {
        // 獲取畫(huà)布
        XSSFChart chart = getSheetDrawing(sheet, chartTitle, startCol, firstRowOffset, endRowOffset, startColOffset, endColOffset);
        //獲取或添加圖例
        XDDFChartLegend legend = chart.getOrAddLegend();
        //設(shè)置圖例的位置
        legend.setPosition(LegendPosition.BOTTOM);
        //創(chuàng)建 類(lèi)別軸 放置底部
        XDDFCategoryAxis bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
        //創(chuàng)建數(shù)據(jù)軸 放置左側(cè)
        XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.LEFT);
//        leftAxis.setTitle(chartTitle);
        //創(chuàng)建數(shù)據(jù)中心  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);
        //數(shù)據(jù)加載
        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);
    }

    /**
     * 創(chuàng)建畫(huà)布
     *
     * @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) {
        //創(chuàng)建一個(gè)畫(huà)布
        XSSFDrawing drawing = sheet.createDrawingPatriarch();
        //前四個(gè)默認(rèn)0,[0,4]:從0列4行開(kāi)始;[7,20]:寬度7個(gè)單元格啊易,20向下擴(kuò)展到20行

        //默認(rèn)寬度(14-8)*12
        int lastRowNum = sheet.getLastRowNum();
        XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, startCol + startColOffset, lastRowNum + firstRowOffset, startCol + endColOffset, lastRowNum + endRowOffset);
        //創(chuàng)建一個(gè)chart對(duì)象
        XSSFChart chart = drawing.createChart(anchor);
        //標(biāo)題
        chart.setTitleText(chartTitle);
        //標(biāo)題是否覆蓋圖表
        chart.setTitleOverlay(false);
        return chart;
    }

}

圖片
圖片
圖片
圖片
  • 參考鏈接
https://www.freesion.com/article/3914537989/
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末吁伺,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子租谈,更是在濱河造成了極大的恐慌篮奄,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,284評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件割去,死亡現(xiàn)場(chǎng)離奇詭異窟却,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)呻逆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)夸赫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人咖城,你說(shuō)我怎么就攤上這事茬腿。” “怎么了宜雀?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,614評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵切平,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我辐董,道長(zhǎng)悴品,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,671評(píng)論 1 293
  • 正文 為了忘掉前任简烘,我火速辦了婚禮苔严,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘孤澎。我一直安慰自己届氢,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,699評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布亥至。 她就那樣靜靜地躺著悼沈,像睡著了一般。 火紅的嫁衣襯著肌膚如雪姐扮。 梳的紋絲不亂的頭發(fā)上絮供,一...
    開(kāi)封第一講書(shū)人閱讀 51,562評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音茶敏,去河邊找鬼壤靶。 笑死,一個(gè)胖子當(dāng)著我的面吹牛惊搏,可吹牛的內(nèi)容都是我干的贮乳。 我是一名探鬼主播,決...
    沈念sama閱讀 40,309評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼恬惯,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼向拆!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起酪耳,我...
    開(kāi)封第一講書(shū)人閱讀 39,223評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤浓恳,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后碗暗,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體颈将,經(jīng)...
    沈念sama閱讀 45,668評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,859評(píng)論 3 336
  • 正文 我和宋清朗相戀三年言疗,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了晴圾。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,981評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡噪奄,死狀恐怖死姚,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情勤篮,我是刑警寧澤知允,帶...
    沈念sama閱讀 35,705評(píng)論 5 347
  • 正文 年R本政府宣布,位于F島的核電站叙谨,受9級(jí)特大地震影響温鸽,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜手负,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,310評(píng)論 3 330
  • 文/蒙蒙 一涤垫、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧竟终,春花似錦蝠猬、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,904評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)柄粹。三九已至,卻和暖如春匆绣,著一層夾襖步出監(jiān)牢的瞬間驻右,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,023評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工崎淳, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留堪夭,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,146評(píng)論 3 370
  • 正文 我出身青樓拣凹,卻偏偏與公主長(zhǎng)得像森爽,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子嚣镜,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,933評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容