近期做的需求中有個(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;
}
}
效果圖
文檔鏈接:http://minio.vm-vas.supremind.io/operation/交通事件統(tǒng)計(jì)--按周期統(tǒng)計(jì).xlsx
圖片
圖片
圖片
圖片
- 參考鏈接
https://www.freesion.com/article/3914537989/