实际项目中遇到的问题,相关信息实在较少,怕自己忘记,菜鸟记录一下
我设置的是双Y轴的组和图表。左侧为折线图Y轴,右侧为柱状图Y轴。
直接上代码。
// An highlighted block
public void hydrographAndRainfallFigureWordExport(HttpServletResponse response) {
//创建文本对象
XWPFDocument document = new XWPFDocument();
CTSectPr sectPr = document.getDocument().getBody().addNewSectPr();
CTPageMar pageMar = sectPr.addNewPgMar();
pageMar.setLeft(BigInteger.valueOf(720L));
pageMar.setTop(BigInteger.valueOf(1440L));
pageMar.setRight(BigInteger.valueOf(720L));
pageMar.setBottom(BigInteger.valueOf(1440L));
try {
//共用X轴数据
List<String> DateList = new ArrayList<>();
DateList.add("2022-01-01");
DateList.add("2022-01-02");
DateList.add("2022-01-03");
DateList.add("2022-01-04");
DateList.add("2022-01-05");
DateList.add("2022-01-06");
String[] categories = {"2022-01-01","2022-01-02","2022-01-03","2022-01-04","2022-01-05","2022-01-06"};
//柱状图Y轴数据
List<Double> HistogramDataList = new ArrayList<>();
HistogramDataList.add(1.74);
HistogramDataList.add(2.31);
HistogramDataList.add(0.65);
HistogramDataList.add(1.42);
HistogramDataList.add(2.00);
HistogramDataList.add(1.73);
Double[] HistogramvaluesA ={1.74,2.31,0.65,1.42,2.00,1.73};
//折线图Y轴数据
List<Double> LineDataList = new ArrayList<>();
LineDataList.add(1.74);
LineDataList.add(2.31);
LineDataList.add(0.65);
LineDataList.add(1.42);
LineDataList.add(2.00);
LineDataList.add(1.73);
Double[] LinevaluesA = {1.74,2.31,0.65,1.42,2.00,1.73} ;
//-----------------------------------------柱状图-------------------------------------------------
// 设置图表大小
XWPFChart chart = document.createChart(15 * Units.EMU_PER_CENTIMETER, 5 * Units.EMU_PER_CENTIMETER);
//创建相关数据
int numOfPoints = categories.length;
String categoryDataRange = chart.formatRange(new CellRangeAddress(1, numOfPoints, 0, 0));
String valuesDataRangeA = chart.formatRange(new CellRangeAddress(1, numOfPoints, 1, 1));
XDDFDataSource<String> categoriesData = XDDFDataSourcesFactory.fromArray(categories, categoryDataRange, 1);
XDDFNumericalDataSource<Double> valuesDataA = XDDFDataSourcesFactory.fromArray(HistogramvaluesA, valuesDataRangeA, 1);
//创建X轴
XDDFCategoryAxis bottomAxis = chart.createCategoryAxis(AxisPosition.TOP);
// 左Y轴
XDDFValueAxis leftAxis = chart.createValueAxis(AxisPosition.LEFT);
// 左Y轴和X轴交叉点在X轴0点位置,在这里我直接注释掉了。
// leftAxis.setCrosses(AxisCrosses.AUTO_ZERO);
// leftAxis.setCrossBetween(AxisCrossBetween.BETWEEN);
// 构建坐标轴
leftAxis.crossAxis(bottomAxis);
bottomAxis.crossAxis(leftAxis);
//设置柱状图Y轴名称,方位和坐标轴大小
leftAxis.setTitle("降雨量/mm");
leftAxis.setCrosses(AxisCrosses.MAX);
leftAxis.setCrossBetween(AxisCrossBetween.BETWEEN);
// create series
bottomAxis.setMajorTickMark(AxisTickMark.NONE);//取消X轴的标刻度
//获取X轴 图表的基本配置都在这个对象里面里面
CTCatAx catAx = chart.getCTChart().getPlotArea().getCatAxArray(0);
CTSkip ctSkip = CTSkip.Factory.newInstance();
//设置显示间隔
ctSkip.setVal((int) Math.ceil(1));
catAx.setTickLblSkip(ctSkip);
//设置标签位置为最下
CTTickLblPos ctTickLblPos = CTTickLblPos.Factory.newInstance();
ctTickLblPos.setVal(STTickLblPos.LOW);
catAx.setTickLblPos(ctTickLblPos);
//获取Y轴 图表的基本配置都在这个对象里面里面
CTValAx catAy = chart.getCTChart().getPlotArea().getValAxArray(0);
CTScaling ctScaling ;
ctScaling = catAy.addNewScaling();
//设置柱状图Y轴坐标最大值
ctScaling.addNewMax().setVal(8);
ctScaling.addNewOrientation().setVal(STOrientation.MAX_MIN);
catAy.setScaling(ctScaling);
// 设置图表背后的网格线
CTLineProperties ctLine = catAy.addNewMajorGridlines().addNewSpPr().addNewLn();
ctLine.addNewPrstDash().setVal(STPresetLineDashVal.DASH);
//创建柱状图数据对象
XDDFChartData data = chart.createData(ChartTypes.BAR, bottomAxis, leftAxis);
((XDDFBarChartData) data).setBarDirection(BarDirection.COL);
//柱状图图例标题
XDDFChartData.Series series = data.addSeries(categoriesData, valuesDataA);
series.setTitle("下雨量", setTitleInDataSheet(chart, "", 0));
chart.plot(data);
//-----------------------------------------折线图-------------------------------------------------
// 右Y轴
XDDFValueAxis rightAxis = chart.createValueAxis(AxisPosition.RIGHT);
// 右Y轴和X轴交叉点在X轴最大值位置
rightAxis.setCrosses(AxisCrosses.MIN);
rightAxis.setCrossBetween(AxisCrossBetween.BETWEEN);
// 构建坐标轴
rightAxis.crossAxis(bottomAxis);
bottomAxis.crossAxis(rightAxis);
//设置折线图Y轴名称
rightAxis.setTitle("水位/m");
XDDFCategoryDataSource countries = XDDFDataSourcesFactory.fromArray(categories);
//设置折线图Y轴坐标最大值
rightAxis.setMaximum(8);
//LINE:折线图,
data = chart.createData(ChartTypes.LINE, bottomAxis, rightAxis);
//加载折线图数据
XDDFNumericalDataSource<Double> area = XDDFDataSourcesFactory.fromArray(LinevaluesA);
//图表加载数据,折线1
XDDFLineChartData.Series series1 = (XDDFLineChartData.Series) data.addSeries(countries, area);
//折线图例标题
series1.setTitle("水位", null);
//直线
series1.setSmooth(true);
//设置标记大小
series1.setMarkerSize((short) 2);
//设置空数据显示间隙
CTDispBlanksAs disp = CTDispBlanksAs.Factory.newInstance();
disp.setVal(STDispBlanksAs.GAP);
chart.getCTChart().setDispBlanksAs(disp);
data.setVaryColors(false);
//绘制
chart.plot(data);
//设置图表图例
XDDFChartLegend legend = chart.getOrAddLegend();
legend.setPosition(LegendPosition.TOP);
//生成word文件,设置文件相关信息。
response.setContentType("application/force-download");// 设置强制下载不打开
response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("折线+柱状组合图.docx", "UTF-8"));
OutputStream out = response.getOutputStream();
document.write(out);
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
//在WORD内生成柱状图所需方法
static CellReference setTitleInDataSheet(XWPFChart chart, String title, int column) {
try {
XSSFWorkbook workbook = null;
workbook = chart.getWorkbook();
XSSFSheet sheet = workbook.getSheetAt(0);
XSSFRow row = sheet.getRow(0);
if (row == null)
row = sheet.createRow(0);
XSSFCell cell = row.getCell(column);
if (cell == null)
cell = row.createCell(column);
cell.setCellValue(title);
return new CellReference(sheet.getSheetName(), 0, column, true, true);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
生成的效果图如下:
实际项目中遇到的问题,相关信息较少,记录一下,防止以后自己忘记。