POI导出excel+JFreeChart生成图表(柱状图和折线图)

根据查询的数据生成excel和图表,excel并且支持分页,这次分页的方法和上一篇文章的方法不同,这次的方法是在查询出数据的时候就开始设置了,在将查询结果写到list集合的时候就分多个集合在存储,最后在将结果添加到另一个list中,如List<List<Object[]>>。最后遍历就可以实现分页的效果。代码:

 

public static void msgExportExcel(String code,SXSSFWorkbook wb, List<Object[]> title,
			List<List<Object[]>> resultList,List<Object[]> chartShow) {
		
		SXSSFSheet sheet =null; 
		File file =null;
		int size = resultList.size();//sheet数
		try {
		for(int i =0;i<size;i++){
			 sheet = (SXSSFSheet) wb.createSheet("Page " + i);  
             Row hrow = sheet.createRow(0);  
            	 Object[] obj = title.get(i);
             //写入标题  
             for(int k=0;k<obj.length;k++){  
                 Cell cell = hrow.createCell(k);  
                 cell.setAsActiveCell();
                 cell.setCellValue(obj[k] == null? "" : obj[k].toString()); 
                 //设置列宽度
                 sheet.setColumnWidth(k, 3500);
            }  
             
            //写入数据
			List<Object[]> list = resultList.get(i);
			for(int j=0;j<list.size();j++){
				Object[] o = list.get(j);
				Row row = sheet.createRow(j+1);
				for (int k = 0; k < o.length; k++) {
					Cell cell = row.createCell(k);
					cell.setCellValue(o[k] == null ? "" : o[k].toString());
				}
				if (i % 100 == 0) {
					sheet.flushRows(100);
				}
			}
			//创建图表
			file = ExportChartUtil.createChartLine(list,chartShow.get(i)[0].toString(),chartShow.get(i)[1].toString()
						,chartShow.get(i)[2].toString(),chartShow.get(i)[3].toString());
			
			imageOut(wb,sheet,file);
		}
	} catch (IOException e) {
		e.printStackTrace();
		logger.error(e.getMessage());
	  }
  }

下面就是生成柱状图和折线图了,方法如:

折线图:

public static File createChartLine(List<Object[]> list,String title,String xTitle,String yTitle,String num){
		
//	public static void main(String args[]){
		//构造数据集合
		DefaultCategoryDataset dataset = new DefaultCategoryDataset();
		for(int i=0;list!=null && i<list.size();i++){
			Object [] obj = list.get(i);
			dataset.addValue(Integer.parseInt(obj[0].toString()),"数据",obj[1].toString()+"\n"+obj[2].toString());
		}
		
		//核心对象
		JFreeChart chart = ChartFactory.createLineChart(title, 	//图形的主标题
											xTitle, 				//X轴外标签的名称
											yTitle, 						//Y轴外标签的名称
											dataset, 
											PlotOrientation.VERTICAL,	//图形的显示方式(水平和垂直) 
											true,						//是否显示子标题 					
											true,						//是否在图形上显示数值的提示 
											true);						//是否生成URL地址
		//解决主标题的乱码
		chart.getTitle().setFont(new Font("宋体", Font.BOLD, 18));
		//解决子标题的乱码
		chart.getLegend().setItemFont(new Font("宋体", Font.BOLD, 15));
		chart.getLegend().setPosition(RectangleEdge.RIGHT);//右侧显示子菜单
		//获取图表区域对象
		CategoryPlot categoryPlot = (CategoryPlot) chart.getPlot();
//		categoryPlot.setBackgroundPaint(null);
		//获取X轴对象
		CategoryAxis categoryAxis = (CategoryAxis) categoryPlot.getDomainAxis();
		//获取Y轴对象
		NumberAxis numberAxis = (NumberAxis) categoryPlot.getRangeAxis();
		//解决X轴上的乱码
		categoryAxis.setTickLabelFont(new Font("宋体", Font.BOLD, 15));
		//解决X轴外的乱码
		categoryAxis.setLabelFont(new Font("宋体", Font.BOLD, 15));
		//解决Y轴上的乱码
		numberAxis.setTickLabelFont(new Font("宋体", Font.BOLD, 15));
		//解决Y轴外的乱码
		numberAxis.setLabelFont(new Font("宋体", Font.BOLD, 15));

		//改变Y轴的刻度,默认值从1计算
		numberAxis.setAutoTickUnitSelection(false);
		NumberTickUnit unit = new NumberTickUnit(Integer.parseInt(num));
		numberAxis.setTickUnit(unit);
		
		//获取绘图区域对象
		LineAndShapeRenderer lineAndShapeRenderer = (LineAndShapeRenderer)categoryPlot.getRenderer();
		lineAndShapeRenderer.setBaseShapesVisible(true);//设置转折点
		
		//让数值显示到页面上
		lineAndShapeRenderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator());
		lineAndShapeRenderer.setBaseItemLabelsVisible(true);
		lineAndShapeRenderer.setBaseItemLabelFont(new Font("宋体", Font.BOLD, 15));
		
		//显示图形
//		ChartFrame chartFrame = new ChartFrame("xyz", chart);
//		chartFrame.setVisible(true);
//		chartFrame.pack();
		
		String filename = DateFormatUtils.format(new Date(), "yyyyMMddHHmmss")+".png";//用时间作为文件名防止重名的问题发生
		File file = new File(filename);//保存文件到web容器中
		try {
			ChartUtilities.saveChartAsPNG(file,chart,600,500);
		} catch (IOException e) {
			e.printStackTrace();
			logger.error(e.getMessage());
		}
		
		return file;
	}

柱状图:

 

public static File createChartBar(List<Object[]> list,String title,String xTitle,String yTitle,String num){
		
		DefaultCategoryDataset dataset = new DefaultCategoryDataset(); 
		for(int i=0;list!=null && i<list.size();i++){
			Object [] obj = list.get(i);
			dataset.addValue(Integer.parseInt(obj[0].toString()),"数据",obj[1].toString()+"\n"+obj[2].toString());
		}

		JFreeChart  chart = ChartFactory.createBarChart(title, //图表的主标题 
											xTitle,//X轴(种类轴)外的标题
											yTitle,//Y轴(值轴)外的标题 
											dataset,  //数据的集合
											PlotOrientation.VERTICAL, //图形的显示形式(水平/垂直)
											true, //是否生成子标题 
											true, //是否生成提示的工具
											true);  //是否在图像上生成URL路径
		
		//处理乱码
		//处理主标题乱码
		chart.getTitle().setFont(new Font("宋体",Font.BOLD,18));
		//处理子标题乱码
		chart.getLegend().setItemFont(new Font("宋体",Font.BOLD,15));
		chart.getLegend().setPosition(RectangleEdge.RIGHT);//右侧显示子菜单
		//调出图表区域对象
		CategoryPlot categoryPlot = (CategoryPlot) chart.getPlot();
		//获取到X轴
		CategoryAxis categoryAxis = (CategoryAxis) categoryPlot.getDomainAxis();
		//获取到Y轴
		NumberAxis numberAxis = (NumberAxis) categoryPlot.getRangeAxis();
		//处理X轴外的乱码
		categoryAxis.setLabelFont(new Font("宋体",Font.BOLD,15));
		//处理X轴上的乱码
		categoryAxis.setTickLabelFont(new Font("宋体",Font.BOLD,15));
		//处理Y轴外的乱码
		numberAxis.setLabelFont(new Font("宋体",Font.BOLD,15));
		//处理Y轴上的乱码
		numberAxis.setTickLabelFont(new Font("宋体",Font.BOLD,15));
		
		//处理Y轴上的刻度,默认从1开始
		numberAxis.setAutoTickUnitSelection(false);
		NumberTickUnit unit = new NumberTickUnit(Integer.parseInt(num));
		numberAxis.setTickUnit(unit);
		
		//处理图形,先要获取绘图区域对象
		BarRenderer barRenderer = (BarRenderer) categoryPlot.getRenderer();
		//设置图形的宽度
//		barRenderer.setMaximumBarWidth(0.1);
		
		//在图形上显示对应数值
		barRenderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator());
		barRenderer.setBaseItemLabelsVisible(true);
		barRenderer.setBaseItemLabelFont(new Font("宋体",Font.BOLD,15));
		
		String filename = DateFormatUtils.format(new Date(), "yyyyMMddHHmmss")+".png";
		File file = new File(filename);
		try {
			 ChartUtilities.saveChartAsPNG(file,chart,600,500);
		} catch (IOException e) {
			e.printStackTrace();
			logger.error(e.getMessage());
		}
		
		return file;
	}

关键的问题就是如何将生成的图表写入到excel中呢?这个时候就需要IO流来完成了,代码如下:

 

private static void imageOut(SXSSFWorkbook wb,SXSSFSheet sheet,File file) {
		
		ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream();
		BufferedImage bufferImg;
		try {
			bufferImg = ImageIO.read(file);
			ImageIO.write(bufferImg, "png", byteArrayOut);
			Drawing dp = sheet.createDrawingPatriarch();
			XSSFClientAnchor anchor = new XSSFClientAnchor(0,0,512,255,7,4,10,20);//设置图表在excel中位置
			anchor.setAnchorType(2);
			dp.createPicture(anchor,wb.addPicture(byteArrayOut.toByteArray(),wb.PICTURE_TYPE_PNG)).resize(0.8);
			
		} catch (IOException e) {
			e.printStackTrace();
			logger.error(e.getMessage());
		}
		
	}

 

在生成excel后最好将在容器中生成的图表删除:

 

 

if(file.exists()){
			file.delete();
		}

扫描下方二维码关注公众号,及时获取文章推送

 

 

 

 

 

 

  • 2
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
您可以使用POI库来导出Excel折线图,并且可以设置线条为虚线。下面是一个示例代码,展示了如何使用POI来实现这个功能: ```java import org.apache.poi.ss.usermodel.*; import org.apache.poi.xssf.usermodel.*; import java.io.FileOutputStream; import java.io.IOException; public class ExcelChartExample { public static void main(String[] args) { // 创建一个新的Excel工作簿 Workbook workbook = new XSSFWorkbook(); Sheet sheet = workbook.createSheet("折线图示例"); // 创建一个数据源 Row row1 = sheet.createRow(0); row1.createCell(0).setCellValue(1); row1.createCell(1).setCellValue(2); row1.createCell(2).setCellValue(3); row1.createCell(3).setCellValue(4); Row row2 = sheet.createRow(1); row2.createCell(0).setCellValue(5); row2.createCell(1).setCellValue(6); row2.createCell(2).setCellValue(7); row2.createCell(3).setCellValue(8); // 创建一个折线图 Drawing drawing = sheet.createDrawingPatriarch(); ClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 4, 0, 10, 20); Chart chart = drawing.createChart(anchor); ChartLegend legend = chart.getOrCreateLegend(); legend.setPosition(LegendPosition.BOTTOM); LineChartData data = chart.getChartDataFactory().createLineChartData(); // 创建折线 ChartAxis bottomAxis = chart.getChartAxisFactory().createCategoryAxis(AxisPosition.BOTTOM); ValueAxis leftAxis = chart.getChartAxisFactory().createValueAxis(AxisPosition.LEFT); leftAxis.setCrosses(AxisCrosses.AUTO_ZERO); ChartDataSource<Number> xs = DataSources.fromNumericCellRange(sheet, new CellRangeAddress(0, 0, 0, 3)); ChartDataSource<Number> ys1 = DataSources.fromNumericCellRange(sheet, new CellRangeAddress(1, 1, 0, 3)); ChartDataSource<Number> ys2 = DataSources.fromNumericCellRange(sheet, new CellRangeAddress(2, 2, 0, 3)); LineChartSeries series1 = data.addSeries(xs, ys1); series1.setTitle(sheet.getRow(1).getCell(0).getStringCellValue()); LineChartSeries series2 = data.addSeries(xs, ys2); series2.setTitle(sheet.getRow(2).getCell(0).getStringCellValue()); // 设置线条样式为虚线 CTChartLines lines1 = series1.getCTLineSer().addNewSpPr().addNewLn().addNewPr(); lines1.addNewDash().setVal(new byte[]{4, 4}); CTChartLines lines2 = series2.getCTLineSer().addNewSpPr().addNewLn().addNewPr(); lines2.addNewDash().setVal(new byte[]{4, 4}); // 将图表添加到工作表 chart.plot(data, bottomAxis, leftAxis); // 保存Excel文件 try { FileOutputStream fileOut = new FileOutputStream("折线图示例.xlsx"); workbook.write(fileOut); fileOut.close(); workbook.close(); System.out.println("Excel文件导出成功!"); } catch (IOException e) { e.printStackTrace(); } } } ``` 这个示例代码会创建一个包含折线图Excel文件,并且将线条样式设置为虚线。您可以根据需要修改数据源和线条样式的设置。请确保将POI库添加到项目的依赖中。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值