Maven
<dependency> <groupId>jfree</groupId> <artifactId>jfreechart</artifactId> <version>1.0.13</version> </dependency>
Java
import org.apache.poi.ss.usermodel.Drawing; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.xssf.streaming.SXSSFWorkbook; import org.apache.poi.xssf.usermodel.XSSFClientAnchor; import org.jfree.chart.ChartColor; import org.jfree.chart.ChartFactory; import org.jfree.chart.ChartUtilities; import org.jfree.chart.JFreeChart; import org.jfree.chart.axis.*; import org.jfree.chart.labels.StandardCategoryItemLabelGenerator; import org.jfree.chart.labels.StandardPieSectionLabelGenerator; import org.jfree.chart.plot.CategoryPlot; import org.jfree.chart.plot.PiePlot3D; import org.jfree.chart.plot.PlotOrientation; import org.jfree.chart.renderer.category.BarRenderer; import org.jfree.chart.renderer.category.LineAndShapeRenderer; import org.jfree.chart.title.LegendTitle; import org.jfree.chart.title.TextTitle; import org.jfree.data.category.CategoryDataset; import org.jfree.data.category.DefaultCategoryDataset; import org.jfree.data.general.DefaultPieDataset; import org.jfree.data.general.PieDataset; import org.jfree.ui.RectangleEdge; import org.springframework.util.CollectionUtils; import org.springframework.util.StringUtils; import javax.imageio.ImageIO; import java.awt.*; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.text.DecimalFormat; import java.text.NumberFormat; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class JfreeChartUtil { // 图片起始位置/左 private static short LEFT_INDEX = 1; // 图片起始位置/上 private static short TOP_INDEX = 1; // 图片起始位置/右 private static short RIGHT_INDEX = 12; // 图片起始位置/下 private static short BOTTOM_INDEX = 15; public JfreeChartUtil() { } public JfreeChartUtil(short LEFT_INDEX, short TOP_INDEX, short RIGHT_INDEX, short BOTTOM_INDEX) { this.LEFT_INDEX = LEFT_INDEX; this.TOP_INDEX = TOP_INDEX; this.RIGHT_INDEX = RIGHT_INDEX; this.BOTTOM_INDEX = BOTTOM_INDEX; } /** * 生成饼状图 */ public void createPinChart(Map<String, Object> pinChartDataMap, SXSSFWorkbook workbook, Drawing drawing) { String title = StringUtils.isEmpty(pinChartDataMap.get("title").toString()) ? "" : pinChartDataMap.get("title").toString(); executePinChart(title, workbook, pieData(pinChartDataMap), drawing, LEFT_INDEX, TOP_INDEX, RIGHT_INDEX, BOTTOM_INDEX); } /** * 生成柱状图 */ public void createBarChart(Map<String, Object> chartDataMap, SXSSFWorkbook workbook, Drawing drawing) { String title = StringUtils.isEmpty(chartDataMap.get("title").toString()) ? "" : chartDataMap.get("title").toString(); executeBarChart(title, chartData(chartDataMap), workbook, drawing, LEFT_INDEX, TOP_INDEX, RIGHT_INDEX, BOTTOM_INDEX); } /** * 生成折线图 */ public void createLineChart(List<Map<String, Object>> lineChartDataList, SXSSFWorkbook workbook, Drawing drawing) { for (Map<String, Object> resultMap : lineChartDataList) { String title = StringUtils.isEmpty(resultMap.get("title").toString()) ? "" : resultMap.get("title").toString(); executeLineChart(title, chartData(resultMap), workbook, drawing, LEFT_INDEX, TOP_INDEX, RIGHT_INDEX, BOTTOM_INDEX); // 图片整体向右位移12单元格 // 左边距位移12 LEFT_INDEX += 12; // 右边距位移12 RIGHT_INDEX += 12; } } // 饼状图数据组合 public PieDataset pieData(Map<String, Object> pinChartDataMap) { List dataList = (List) pinChartDataMap.get("dataList"); List keyList = (List) pinChartDataMap.get("keyList"); if (!CollectionUtils.isEmpty(dataList)) { if (dataList.size() == keyList.size()) { DefaultPieDataset dataSet = new DefaultPieDataset(); for (int i = 0; i < dataList.size(); i++) { dataSet.setValue(keyList.get(i).toString(), Integer.parseInt(dataList.get(i).toString())); } return dataSet; } } return null; } // 柱状图/折线图数据组合 public DefaultCategoryDataset chartData(Map<String, Object> resultMap) { List<Object> keyList = (List<Object>) resultMap.get("keyList"); List<Object> dataList = (List<Object>) resultMap.get("dataList"); DefaultCategoryDataset dataSet = new DefaultCategoryDataset(); for (int i = 0; i < dataList.size(); i++) { dataSet.addValue(Integer.parseInt(dataList.get(i).toString()), resultMap.get("title").toString(), keyList.get(i).toString()); } return dataSet; } /** * 执行生成饼状图 * * @param title * @param workbook * @param dataSet * @param drawing * @param LEFT_INDEX * @param TOP_INDEX * @param RIGHT_INDEX * @param BOTTOM_INDEX */ public void executePinChart(String title, SXSSFWorkbook workbook, PieDataset dataSet, Drawing drawing, short LEFT_INDEX, short TOP_INDEX, short RIGHT_INDEX, short BOTTOM_INDEX) { try { JFreeChart chart = ChartFactory.createPieChart3D( title, // 图表标题 dataSet, // 数据集 true, // 显示label true, // 显示提示 true); // 显示urls // 使下说明标签字体清晰 chart.getRenderingHints().put(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF); chart.setTextAntiAlias(false); // 图片背景色 chart.setBackgroundPaint(Color.white); // 设置图标题的字体重新设置title Font font = new Font("simsun", Font.BOLD, 25); TextTitle textTitle = new TextTitle(title); textTitle.setFont(font); chart.setTitle(title); PiePlot3D plot = (PiePlot3D) chart.getPlot(); // 图片中显示百分比:默认方式 // 指定饼图轮廓线的颜色 // plot.setBaseSectionOutlinePaint(Color.BLACK); // plot.setBaseSectionPaint(Color.BLACK); // 设置无数据时的信息 plot.setNoDataMessage("NO DATAS"); // 设置无数据时的信息显示颜色 plot.setNoDataMessagePaint(Color.red); // 图片中显示百分比:自定义方式,{0} 表示选项, {1} 表示数值, {2} 表示所占比例 ,小数点后两位 plot.setLabelGenerator(new StandardPieSectionLabelGenerator( "{0}={1}({2})", NumberFormat.getNumberInstance(), new DecimalFormat("0.00%"))); // 图例显示百分比:自定义方式, {0} 表示选项, {1} 表示数值, {2} 表示所占比例 plot.setLegendLabelGenerator(new StandardPieSectionLabelGenerator( "{0}={1}({2})")); plot.setLabelFont(new Font("simsun", Font.TRUETYPE_FONT, 12)); // 指定图片的透明度(0.0-1.0) plot.setForegroundAlpha(0.65f); // 指定显示的饼图上圆形(false)还椭圆形(true) plot.setCircular(false, true); // 设置第一个 饼块section 的开始位置,默认是12点钟方向 plot.setStartAngle(90); ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); try { ChartUtilities.writeChartAsPNG(byteArrayOutputStream, chart, 400, 200); String fileSavePath = "exTest.png"; BufferedImage bufferImg = ImageIO.read(new File(fileSavePath)); ImageIO.write(bufferImg, "png", byteArrayOutputStream); } catch (IOException e) { } // 八个参数,前四个表示图片离起始单元格和结束单元格边缘的位置, // 后四个表示起始和结束单元格的位置,需要注意excel起始位置是0 XSSFClientAnchor anchor = new XSSFClientAnchor(0, 0, 0, 0, LEFT_INDEX, TOP_INDEX, RIGHT_INDEX, BOTTOM_INDEX); anchor.setAnchorType(3); // 插入图片 drawing.createPicture(anchor, workbook.addPicture(byteArrayOutputStream.toByteArray(), SXSSFWorkbook.PICTURE_TYPE_PNG)); } catch (Exception e) { e.printStackTrace(); } } /** * 执行生成柱状图 * * @param title * @param dataSet * @param workbook * @param drawing * @param LEFT_INDEX * @param TOP_INDEX * @param RIGHT_INDEX * @param BOTTOM_INDEX */ public void executeBarChart(String title, CategoryDataset dataSet, SXSSFWorkbook workbook, Drawing drawing, short LEFT_INDEX, short TOP_INDEX, short RIGHT_INDEX, short BOTTOM_INDEX) { JFreeChart chart = ChartFactory.createBarChart( title, // 图表标题 "", // 目录轴的显示标签 "", // 数值轴的显示标签 dataSet, // 数据集 PlotOrientation.VERTICAL, // 图表方向:水平、垂直 true, // 是否显示图例(对于简单的柱状图必须是false) false, // 是否生成工具 false // 是否生成URL链接 ); Font labelFont = new Font("simsun", Font.TRUETYPE_FONT, 12); /* * VALUE_TEXT_ANTIALIAS_OFF表示将文字的抗锯齿关闭, * 使用的关闭抗锯齿后,字体尽量选择12到14号的宋体字,这样文字最清晰好看 */ // chart.getRenderingHints().put(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_OFF); chart.setTextAntiAlias(false); chart.setBackgroundPaint(Color.white); // create plot CategoryPlot plot = chart.getCategoryPlot(); // 设置横虚线可见 plot.setRangeGridlinesVisible(true); // 虚线色彩 plot.setRangeGridlinePaint(Color.gray); // 数据轴精度 NumberAxis vn = (NumberAxis) plot.getRangeAxis(); // vn.setAutoRangeIncludesZero(true); DecimalFormat df = new DecimalFormat("#0.00"); vn.setNumberFormatOverride(df); // 数据轴数据标签的显示格式 // x轴设置 CategoryAxis domainAxis = plot.getDomainAxis(); domainAxis.setLabelFont(labelFont);// 轴标题 domainAxis.setTickLabelFont(labelFont);// 轴数值 // Lable(Math.PI/3.0)度倾斜 // domainAxis.setCategoryLabelPositions(CategoryLabelPositions // .createUpRotationLabelPositions(Math.PI / 3.0)); domainAxis.setMaximumCategoryLabelWidthRatio(0.6f);// 横轴上的 Lable 是否完整显示 // 设置距离图片左端距离 domainAxis.setLowerMargin(0.1); // 设置距离图片右端距离 domainAxis.setUpperMargin(0.1); // 设置 columnKey 是否间隔显示 // domainAxis.setSkipCategoryLabelsToFit(true); plot.setDomainAxis(domainAxis); // 设置柱图背景色(注意,系统取色的时候要使用16位的模式来查看颜色编码,这样比较准确) plot.setBackgroundPaint(new Color(255, 255, 255)); // y轴设置 ValueAxis rangeAxis = plot.getRangeAxis(); rangeAxis.setLabelFont(labelFont); rangeAxis.setTickLabelFont(labelFont); // 设置最高的一个 Item 与图片顶端的距离 rangeAxis.setUpperMargin(0.15); // 设置最低的一个 Item 与图片底端的距离 rangeAxis.setLowerMargin(0.15); plot.setRangeAxis(rangeAxis); BarRenderer renderer = new BarRenderer(); // 设置柱子宽度 renderer.setMaximumBarWidth(0.05); // 设置柱子高度 renderer.setMinimumBarLength(0.2); // 设置柱子边框颜色 renderer.setBaseOutlinePaint(Color.BLACK); // 设置柱子边框可见 renderer.setDrawBarOutline(true); // 设置每个地区所包含的平行柱的之间距离 renderer.setItemMargin(0.0); // 显示每个柱的数值,并修改该数值的字体属性 renderer.setIncludeBaseInRange(true); renderer .setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator()); renderer.setBaseItemLabelsVisible(true); plot.setRenderer(renderer); // 设置柱的透明度 plot.setForegroundAlpha(1.0f); ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); try { ChartUtilities.writeChartAsPNG(byteArrayOutputStream, chart, 400, 200); String fileSavePath = "exTest.png"; BufferedImage bufferImg = ImageIO.read(new File(fileSavePath)); ImageIO.write(bufferImg, "png", byteArrayOutputStream); } catch (IOException e) { } // 八个参数,前四个表示图片离起始单元格和结束单元格边缘的位置, // 后四个表示起始和结束单元格的位置,需要注意excel起始位置是0 XSSFClientAnchor anchor = new XSSFClientAnchor(0, 0, 0, 0, LEFT_INDEX, TOP_INDEX, RIGHT_INDEX, BOTTOM_INDEX); anchor.setAnchorType(3); // 插入图片 drawing.createPicture(anchor, workbook.addPicture(byteArrayOutputStream.toByteArray(), SXSSFWorkbook.PICTURE_TYPE_PNG)); } /** * 执行生成折线图 * * @param title * @param dataSet * @param workbook * @param drawing * @param LEFT_INDEX * @param TOP_INDEX * @param RIGHT_INDEX * @param BOTTOM_INDEX */ public void executeLineChart(String title, DefaultCategoryDataset dataSet, SXSSFWorkbook workbook, Drawing drawing, short LEFT_INDEX, short TOP_INDEX, short RIGHT_INDEX, short BOTTOM_INDEX) { try { JFreeChart chart = ChartFactory.createLineChart( title, // 图表标题 "", "", dataSet, // 数据集 PlotOrientation.VERTICAL, // 图表放置模式水平/垂直 true, // 显示label true, // 显示提示 true); // 显示urls // 设置图片中的字体和颜色以及字号 Font titleFont = new Font("simsun", Font.BOLD, 14); Font xFont = new Font("simsun", Font.BOLD, 12); Font labelFont = new Font("simsun", Font.BOLD, 12); // 设置图例字体 chart.getLegend().setItemFont(new Font("simsun", Font.BOLD, 10)); // 设置标题字体 chart.setTitle(new TextTitle(chart.getTitle().getText(), titleFont)); // 图形的绘制结构对象 CategoryPlot plot = chart.getCategoryPlot(); // 获取显示线条的对象 LineAndShapeRenderer lineAndShapeRenderer = (LineAndShapeRenderer) plot.getRenderer(); // 设置拐点是否可见/是否显示拐点 lineAndShapeRenderer.setBaseShapesVisible(false); // 设置拐点不同用不同的形状 lineAndShapeRenderer.setDrawOutlines(true); // 设置线条是否被显示填充颜色 lineAndShapeRenderer.setUseFillPaint(true); LineAndShapeRenderer renderer = (LineAndShapeRenderer) plot.getRenderer(); // 设置折线大小以及折线的颜色 renderer.setSeriesStroke(0, new BasicStroke(1.0F)); renderer.setSeriesPaint(0, new Color(255, 0, 9)); // 设置折点的大小 lineAndShapeRenderer.setSeriesOutlineStroke(0, new BasicStroke(0.025F)); lineAndShapeRenderer.setSeriesOutlineStroke(1, new BasicStroke(0.05F)); // 设置网格线 plot.setDomainGridlinePaint(Color.gray); plot.setDomainGridlinesVisible(true); plot.setRangeGridlinePaint(Color.gray); plot.setRangeGridlinesVisible(true); // x轴 CategoryAxis domainAxis = plot.getDomainAxis(); // 设置x轴不显示,即让x轴和数据区重合 domainAxis.setAxisLineVisible(false); // x轴标题 domainAxis.setLabelFont(xFont); // x轴数据倾斜 domainAxis.setCategoryLabelPositions(CategoryLabelPositions.createUpRotationLabelPositions(0.95D)); // X轴坐标上数值字体 domainAxis.setTickLabelFont(labelFont); // 设置Y轴间隔 NumberAxis numAxis = (NumberAxis) plot.getRangeAxis(); numAxis.setTickUnit(new NumberTickUnit(50)); // y轴 ValueAxis rangeAxis = plot.getRangeAxis(); rangeAxis.setLabelFont(xFont); // 设置y轴不显示,即和数据区重合 rangeAxis.setAxisLineVisible(false); // y轴坐标上数值字体 rangeAxis.setTickLabelFont(labelFont); rangeAxis.setFixedDimension(0); CategoryPlot categoryPlot = chart.getCategoryPlot(); // 背景色设置 categoryPlot.setBackgroundPaint(ChartColor.WHITE); categoryPlot.setRangeGridlinePaint(ChartColor.GRAY); // 创建图例,设置图例的位置,这里的设置实际不起作用,怎么设都在下边 LegendTitle legendTitle = new LegendTitle(chart.getPlot()); legendTitle.setPosition(RectangleEdge.BOTTOM); ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); try { ChartUtilities.writeChartAsPNG(byteArrayOutputStream, chart, 400, 200); String fileSavePath = "exTest.png"; BufferedImage bufferImg = ImageIO.read(new File(fileSavePath)); ImageIO.write(bufferImg, "png", byteArrayOutputStream); } catch (IOException e) { } // 八个参数,前四个表示图片离起始单元格和结束单元格边缘的位置, // 后四个表示起始和结束单元格的位置,顺序为左/上/右/下,需要注意EXCEL单元格起始位置是0 XSSFClientAnchor anchor = new XSSFClientAnchor(0, 0, 0, 0, LEFT_INDEX, TOP_INDEX, RIGHT_INDEX, BOTTOM_INDEX); anchor.setAnchorType(3); // 插入图片 drawing.createPicture(anchor, workbook.addPicture(byteArrayOutputStream.toByteArray(), SXSSFWorkbook.PICTURE_TYPE_PNG)); } catch (Exception e) { e.printStackTrace(); } } /** * 生成文件 * * @param fileOutputStream * @param workbook * @throws IOException */ public static void outputExcel(FileOutputStream fileOutputStream, SXSSFWorkbook workbook) throws IOException { try { fileOutputStream = new FileOutputStream("C:\\Users\\XXX\\Desktop\\" + System.currentTimeMillis() + ".xlsx"); workbook.write(fileOutputStream); } catch (Exception e) { e.printStackTrace(); } finally { fileOutputStream.close(); } } public static void main(String[] args) { JfreeChartUtil jfreeChartUtil = new JfreeChartUtil(); SXSSFWorkbook workbook = new SXSSFWorkbook(); Sheet sheet = workbook.createSheet(); // 画图的顶级管理器,一个sheet只能获取一个(一定要注意这点) Drawing drawing = sheet.createDrawingPatriarch(); FileOutputStream fileOutputStream = null; try { // 饼状图 jfreeChartUtil.createPinChart(pinChartDataMap(), workbook, drawing); // 图片右移12单元格 LEFT_INDEX += 12; RIGHT_INDEX += 12; // 柱状图 jfreeChartUtil.createBarChart(barChartDataMap(), workbook, drawing); // 图片右移12单元格 LEFT_INDEX += 12; RIGHT_INDEX += 12; // 折线图 jfreeChartUtil.createLineChart(lineChartDataList(), workbook, drawing); // 输出文件 outputExcel(fileOutputStream, workbook); } catch (Exception e) { e.printStackTrace(); } } /** * 饼状图数据集模拟 * * @return */ public static Map<String, Object> pinChartDataMap() { Map<String, Object> resultMap = new HashMap<>(); resultMap.put("title", "饼状图"); List<Object> keyList = new ArrayList<>(); keyList.add("失败率"); keyList.add("成功率"); List<Object> dataList = new ArrayList<>(); dataList.add(9); dataList.add(90); resultMap.put("keyList", keyList); resultMap.put("dataList", dataList); return resultMap; } /** * 柱状图数据集模拟 * * @return */ public static Map<String, Object> barChartDataMap() { Map<String, Object> resultMap = new HashMap<>(); resultMap.put("title", "苹果柱状图"); List<Object> keyList = new ArrayList<>(); keyList.add("北京"); keyList.add("上海"); keyList.add("广州"); keyList.add("成都"); keyList.add("深圳"); List<Object> dataList = new ArrayList<>(); dataList.add(672); dataList.add(766); dataList.add(223); dataList.add(540); dataList.add(126); resultMap.put("keyList", keyList); resultMap.put("dataList", dataList); return resultMap; } /** * 折线图数据集模拟 * * @return */ public static List<Map<String, Object>> lineChartDataList() { List<Map<String, Object>> resultList = new ArrayList<>(); // 设置具体数据 List<Object> keyList = new ArrayList<>(); keyList.add("2018-12-09"); keyList.add("2018-12-10"); keyList.add("2018-12-11"); keyList.add("2018-12-12"); keyList.add("2018-12-13"); keyList.add("2018-12-14"); keyList.add("2018-12-15"); keyList.add("2018-12-16"); keyList.add("2018-12-17"); List<Object> dataList = new ArrayList<>(); dataList.add(100); dataList.add(100); dataList.add(230); dataList.add(200); dataList.add(200); dataList.add(200); dataList.add(150); dataList.add(150); dataList.add(150); Map<String, Object> innerMap = new HashMap<>(); innerMap.put("title", "水果销量折线图"); innerMap.put("keyList", keyList); innerMap.put("dataList", dataList); // 设置具体数据 List<Object> keyList2 = new ArrayList<>(); keyList2.add("09:00"); keyList2.add("10:00"); keyList2.add("11:00"); keyList2.add("12:00"); keyList2.add("13:00"); keyList2.add("14:00"); keyList2.add("15:00"); keyList2.add("16:00"); keyList2.add("17:00"); List<Object> dataList2 = new ArrayList<>(); dataList2.add(100); dataList2.add(230); dataList2.add(100); dataList2.add(200); dataList2.add(200); dataList2.add(200); dataList2.add(150); dataList2.add(150); dataList2.add(150); Map<String, Object> innerMap2 = new HashMap<>(); innerMap2.put("title", "TT销量折线图"); innerMap2.put("keyList", keyList2); innerMap2.put("dataList", dataList2); resultList.add(innerMap); resultList.add(innerMap2); return resultList; } }
原文地址:https://www.cnblogs.com/huahuavip/p/10109812.html
时间: 2024-10-10 09:38:03