我想在一个Excel工作表中生成具有不同系列的多个图表。但是,我可以使用以下代码绘制一个图表但是当我在以下代码中创建第二个XSSFChart图表和XSSFClientAnchor锚点时,它无法在Excel中绘制图表。如何在一个excel中绘制两个或多个折线图。以下代码有什么问题?
public class MultipleChartWithThreeLines {
private static XDDFLineChartData.Series addLineSeriesToChartData(XDDFChartData chartData, XSSFSheet sheet, String categoryDataRef, String valueDataRef, String seriesTitleRef, PresetColor lineColor) {
XDDFDataSource<Double> categoryData = XDDFDataSourcesFactory.fromNumericCellRange(sheet, CellRangeAddress.valueOf(categoryDataRef));
XDDFNumericalDataSource<Double> valueData = XDDFDataSourcesFactory.fromNumericCellRange(sheet, CellRangeAddress.valueOf(valueDataRef));
XDDFLineChartData.Series series = (XDDFLineChartData.Series) chartData.addSeries(categoryData, valueData);
series.setTitle("", new CellReference(seriesTitleRef)); // https://stackoverflow.com/questions/21855842
series.setSmooth(false); // https://stackoverflow.com/questions/29014848
// define data-point marker
series.setMarkerStyle(MarkerStyle.CIRCLE); // https://stackoverflow.com/questions/39636138
// define line color
// https://stackoverflow.com/questions/24676460
XDDFShapeProperties shapeProperties = series.getShapeProperties();
if (shapeProperties == null) {
shapeProperties = new XDDFShapeProperties();
}
shapeProperties.setLineProperties(solidLineWithColor(lineColor));
series.setShapeProperties(shapeProperties);
// if your series have missing values like https://stackoverflow.com/questions/29014848
// chart.displayBlanksAs(DisplayBlanks.GAP);
return series;
}
private static XDDFLineProperties solidLineWithColor(PresetColor color) {
XDDFSolidFillProperties fill = new XDDFSolidFillProperties(XDDFColor.from(color));
XDDFLineProperties line = new XDDFLineProperties();
line.setFillProperties(fill);
return line;
}
private static XDDFChartLegend addLegendToChart(XSSFChart chart) {
XDDFChartLegend legend = chart.getOrAddLegend();
legend.setPosition(LegendPosition.BOTTOM);
return legend;
}
private static XSSFChart createChartOnSheet(XSSFSheet sheet, int col1, int row1, int col2, int row2) {
XSSFDrawing drawing = sheet.createDrawingPatriarch();
XSSFClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, col1, row1, col2, row2);
XSSFChart chart = drawing.createChart(anchor);
return chart;
}
private static XDDFChartAxis[] addAxesToChart(XSSFChart chart, String titleCategoryBottom, String titleValueLeft) {
XDDFChartAxis[] axesCatVal = new XDDFChartAxis[4];
// category axis at the bottom
XDDFCategoryAxis bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
bottomAxis.setTitle(titleCategoryBottom); // https://stackoverflow.com/questions/32010765
axesCatVal[0] = bottomAxis;
// value axis at the left
XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.LEFT);
leftAxis.setTitle(titleValueLeft);
leftAxis.setCrosses(AxisCrosses.AUTO_ZERO);
axesCatVal[1] = leftAxis;
return axesCatVal;
}
private static void writeWorkbookToFile(XSSFWorkbook wb, String filename) throws IOException {
FileOutputStream fileOut = new FileOutputStream(filename);
wb.write(fileOut);
fileOut.close();
}
public static void main(String[] args) throws Exception {
String workbookFilename = "e:/Graph_5.xlsx"; //"e:/Graph_5.xlsx";
// open workbook with data
XSSFWorkbook wb = new XSSFWorkbook(workbookFilename);
// draw chart with 3 lines
XSSFSheet sheet = wb.getSheetAt(0);
String sheetName = sheet.getSheetName();
System.out.println("Drawing line-chart on sheet: " + sheetName);
// create chart
XSSFChart chart = createChartOnSheet(sheet, 6, 0, 25, 15);
XSSFChart medianAngleChart = createChartOnSheet(sheet,10,17,25,15);
// add legend to chart
addLegendToChart(chart);
addLegendToChart(medianAngleChart);
// add value (left) and category (bottom) axes
XDDFChartAxis[] axesCatVal = addAxesToChart(chart, "", "Inscribed Angle"); // Add data (as Line Chart)
XDDFChartAxis[] axesCatVal_1 = addAxesToChart(medianAngleChart, "", "Median Angle"); // Add data (as Line Chart)
// add line-chart data-collection to chart
XDDFLineChartData chartData = (XDDFLineChartData) chart.createData(ChartTypes.LINE, axesCatVal[0], (XDDFValueAxis) axesCatVal[1]);
XDDFLineChartData chartData_1 = (XDDFLineChartData) medianAngleChart.createData(ChartTypes.LINE, axesCatVal_1[0], (XDDFValueAxis) axesCatVal_1[1]);
// Line-1
XDDFLineChartData.Series series1 = addLineSeriesToChartData(chartData
, sheet
,sheetName + "!$B$3:$B$66"
, sheetName + "!$D$3:$D$66"
, sheetName + "!$D$2"
, PresetColor.RED
);
System.out.println("added line 1: \n" + series1);
// Line-2
XDDFLineChartData.Series series2 = addLineSeriesToChartData(chartData
, sheet
,sheetName+"!$B$3:$B$66"
, sheetName+"!$E$3:$E$66"
, sheetName+"!$E$2"
, PresetColor.GREEN
);
System.out.println("added line 2: \n" + series2);
// Line-3
XDDFLineChartData.Series series3 = addLineSeriesToChartData(chartData
, sheet
, sheetName+"!$B$3:$B$66"
, sheetName+"!$F$3:$F$66"
, sheetName+"!$F$2"
, PresetColor.BLUE
);
System.out.println("added line 3: \n" + series3);
//second chart Line-1
XDDFLineChartData.Series series4 = addLineSeriesToChartData(chartData_1
, sheet
, sheetName+"!$B$3:$B$66"
, sheetName+"!$G$3:$G$66"
, sheetName+"!$G$2"
, PresetColor.BLUE
);
System.out.println("added line 4: \n" + series4);
chart.plot(chartData);
medianAngleChart.plot(chartData_1);
// save workbook
writeWorkbookToFile(wb,"ChartWithThreeLines.xlsx");
// close workbook
wb.close();
}
}
不清楚你所展示的代码在哪里出错了。分裂成多种方法真的很难。
但这里有一个完整的例子,它可能显示了做你想做的最简单的方法。
码:
import java.io.*;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.*;
import org.apache.poi.ss.util.*;
import org.apache.poi.xddf.usermodel.*;
import org.apache.poi.xddf.usermodel.chart.*;
public class CreateExcelTwoLineCharts {
public static void main(String[] args) throws IOException {
try (XSSFWorkbook wb = new XSSFWorkbook()) {
// create the data
XSSFSheet sheet = wb.createSheet("Sheet1");
Row row;
Cell cell;
row = sheet.createRow(0);
row.createCell(0).setCellValue("Months");
row.createCell(1).setCellValue("Mountain View");
row.createCell(2).setCellValue("New York");
row.createCell(3).setCellValue("Washington");
row.createCell(4).setCellValue("England");
row.createCell(5).setCellValue("New Zeland");
row.createCell(6).setCellValue("Australia");
for (int r = 1; r < 13; r++) {
row = sheet.createRow(r);
for (int c = 0; c < 7; c++) {
cell = row.createCell(c);
if (c == 0) cell.setCellValue(r);
else cell.setCellFormula("RANDBETWEEN(50, 99)");
}
}
// create data sources
XDDFDataSource<Double> months = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(1, 12, 0, 0));
int c = 1;
XDDFNumericalDataSource<Double> mView = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(1, 12, c, c++));
XDDFNumericalDataSource<Double> nYork = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(1, 12, c, c++));
XDDFNumericalDataSource<Double> washingt = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(1, 12, c, c++));
XDDFNumericalDataSource<Double> engl = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(1, 12, c, c++));
XDDFNumericalDataSource<Double> nZeal = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(1, 12, c, c++));
XDDFNumericalDataSource<Double> austral = XDDFDataSourcesFactory.fromNumericCellRange(sheet, new CellRangeAddress(1, 12, c, c++));
// create sheets drawing
XSSFDrawing drawing = sheet.createDrawingPatriarch();
// needed objeccts for the charts
XSSFClientAnchor anchor;
XSSFChart chart;
XDDFChartLegend legend;
XDDFCategoryAxis bottomAxis;
XDDFValueAxis leftAxis;
XDDFChartData data;
XDDFChartData.Series series;
//======first line chart============================================================
// create anchor
anchor = drawing.createAnchor(0, 0, 0, 0, 8, 0, 14, 12); // anchor col8,row0 to col14,row12
// create chart
chart = drawing.createChart(anchor);
legend = chart.getOrAddLegend();
legend.setPosition(LegendPosition.BOTTOM);
// create the axes
bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
leftAxis = chart.createValueAxis(AxisPosition.LEFT);
leftAxis.setCrosses(AxisCrosses.AUTO_ZERO);
// create chart data
data = chart.createData(ChartTypes.LINE, bottomAxis, leftAxis);
// create series
series = data.addSeries(months, mView);
series.setTitle("Mountain View", new CellReference(sheet.getSheetName(), 0, 1, true, true));
series = data.addSeries(months, nYork);
series.setTitle("New York", new CellReference(sheet.getSheetName(), 0, 2, true, true));
series = data.addSeries(months, washingt);
series.setTitle("Washington", new CellReference(sheet.getSheetName(), 0, 3, true, true));
chart.plot(data);
solidLineSeries(data, 0, PresetColor.BLUE);
solidLineSeries(data, 1, PresetColor.RED);
solidLineSeries(data, 2, PresetColor.GREEN);
//======second line chart============================================================
// create anchor
anchor = drawing.createAnchor(0, 0, 0, 0, 8, 13, 14, 25); // anchor col8,row13 to col14,row25
// create chart
chart = drawing.createChart(anchor);
legend = chart.getOrAddLegend();
legend.setPosition(LegendPosition.BOTTOM);
// create the axes
bottomAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
leftAxis = chart.createValueAxis(AxisPosition.LEFT);
leftAxis.setCrosses(AxisCrosses.AUTO_ZERO);
// create chart data
data = chart.createData(ChartTypes.LINE, bottomAxis, leftAxis);
// create series
series = data.addSeries(months, engl);
series.setTitle("England", new CellReference(sheet.getSheetName(), 0, 4, true, true));
series = data.addSeries(months, nZeal);
series.setTitle("New Zeland", new CellReference(sheet.getSheetName(), 0, 5, true, true));
series = data.addSeries(months, austral);
series.setTitle("Australia", new CellReference(sheet.getSheetName(), 0, 6, true, true));
chart.plot(data);
solidLineSeries(data, 0, PresetColor.BLUE);
solidLineSeries(data, 1, PresetColor.RED);
solidLineSeries(data, 2, PresetColor.GREEN);
// write the output to a file
try (FileOutputStream fileOut = new FileOutputStream("CreateExcelTwoLineCharts.xlsx")) {
wb.write(fileOut);
}
}
}
private static void solidLineSeries(XDDFChartData data, int index, PresetColor color) {
XDDFSolidFillProperties fill = new XDDFSolidFillProperties(XDDFColor.from(color));
XDDFLineProperties line = new XDDFLineProperties();
line.setFillProperties(fill);
XDDFChartData.Series series = data.getSeries().get(index);
XDDFShapeProperties properties = series.getShapeProperties();
if (properties == null) {
properties = new XDDFShapeProperties();
}
properties.setLineProperties(line);
series.setShapeProperties(properties);
}
}
结果: