使用JfreeChart+itextpdf+POI将Excel中的图表和数据导出到PDF

1 篇文章 0 订阅
1 篇文章 0 订阅

使用JfreeChart+itextpdf+POI将Excel中的图表和数据导出到PDF



前言

业务需要将原本的Excel导出改为PDF导出


一、版本说明

	<dependency>
		<groupId>org.apache.poi</groupId>
		<artifactId>poi-ooxml</artifactId>
		<version>4.1.2</version>
	</dependency>
	<dependency>
		<groupId>org.apache.poi</groupId>
		<artifactId>poi-ooxml-schemas</artifactId>
		<version>4.1.2</version>
	</dependency>
	<dependency>
		<groupId>com.itextpdf</groupId>
		<artifactId>itextpdf</artifactId>
		<version>5.5.13.3</version>
	</dependency>

	<dependency>
		<groupId>com.itextpdf</groupId>
		<artifactId>kernel</artifactId>
		<version>7.1.5</version>
	</dependency>
	<dependency>
		<groupId>com.itextpdf</groupId>
		<artifactId>io</artifactId>
		<version>7.1.5</version>
	</dependency>
	<dependency>
		<groupId>com.itextpdf</groupId>
		<artifactId>layout</artifactId>
		<version>7.1.5</version>
	</dependency>
	
	<dependency>
		<groupId>jfree</groupId>
		<artifactId>jcommon</artifactId>
		<version>1.0.16</version>
	</dependency>
	<dependency>
		<groupId>jfree</groupId>
		<artifactId>jfreechart</artifactId>
		<version>1.0.13</version>
	</dependency>

二、使用步骤

1.JfreeChart

由于业务数据X轴是时间,所以关于图表大致有两种可用:

1. JFreeChart chart = ChartFactory.createTimeSeriesChart("title",
				"timeAxisLabel",
				"valueAxisLabel",
				dataSet,
				legend,
				tooltips,
				urls
		);
数据集:
TimeSeries s1 = new TimeSeries(Comparable, Day.class);
s1.addOrUpdate(new Day(businessTime.get(Calendar.DAY_OF_MONTH), businessTime.get(Calendar.MONTH) + 1, businessTime.get(Calendar.YEAR)), Double.valueOf(businessValue));

时序图:通过描述对象之间发送消息的时间顺序显示多个对象之间的动态协作。它可以表示用例的行为顺序。(来自百度百科)
这里注意有个坑就是如果时间是有重复的,可以使用addOrUpdate方法。并且JfreeChart会在渲染数据时,自动按照时间排序。同时将X轴设置个默认的间隔日期. 如果数据不连续,可能造成chart和预想的效果不符合。
![](https://img-blog.csdnimg.cn/916078a61fb9488c847ba2cef71147b4.png)

2. JFreeChart chart = ChartFactory.createLineChart("title",
				"timeAxisLabel",
				"valueAxisLabel",
				dataSet,
				PlotOrientation,
				legend,
				tooltips,
				urls
		);
数据集:
DefaultCategoryDataset dataset = new DefaultCategoryDataset();
dataset.addValue(Double.valueOf(yValue), "type1", xValue));
线图: 常见的线图。		

这里业务最后确认了时间连续可以使用时序图~

2.部分核心代码

代码如下(示例):

private static JFreeChart createTimeSeriesLineChart(String title, List originalDataSet) throws Exception {

		TimeSeriesCollection dataSet = createDataset(originalDataSet);
		StandardChartTheme standardChartTheme = new StandardChartTheme("EN");
		standardChartTheme.setRegularFont(new Font("Arial", Font.PLAIN, 14));
		ChartFactory.setChartTheme(standardChartTheme);
		JFreeChart chart = ChartFactory.createTimeSeriesChart("",
				"Date",
				"Last 100 Value",
				dataSet,
				true,
				false,
				false
		);

		chart.getXYPlot().setRenderer(new XYSplineRenderer(7));
		chart.setBackgroundPaint(Color.white);
		TextTitle t = new TextTitle();
		t.setMargin(0,0,20,0);
		t.setText(title);

		Font f = new Font("Arial", Font.BOLD, 14);
		t.setFont(f);
		t.setTextAlignment(HorizontalAlignment.LEFT);
		chart.setTitle(t);
		XYPlot plot = (XYPlot) chart.getPlot();
		plot.setDomainGridlinesVisible(false);
		plot.setBackgroundPaint(Color.white);
		plot.setOutlineVisible(false);
		plot.setDomainGridlinePaint(Color.LIGHT_GRAY);
		plot.setRangeGridlinePaint(Color.LIGHT_GRAY);
		plot.setAxisOffset(new RectangleInsets(5.0, 5.0, 5.0, 5.0));
		plot.setDomainCrosshairVisible(false);
		plot.setRangeCrosshairVisible(false);
		// set series shapes
		XYItemRenderer xyItemRenderer = plot.getRenderer();
		if (xyItemRenderer instanceof XYLineAndShapeRenderer) {
			XYLineAndShapeRenderer renderer = (XYLineAndShapeRenderer) xyItemRenderer;
			renderer.setSeriesShape(0, new Ellipse2D.Double(0, 0, 0, 0));
			renderer.setSeriesShape(1, new Ellipse2D.Double(-3.0, -3.0, 6.0, 6.0));
			renderer.setSeriesShape(2, new Ellipse2D.Double(0, 0, 0, 0));
			renderer.setSeriesShape(3, new Ellipse2D.Double(0, 0, 0, 0));
			renderer.setSeriesStroke(0, new BasicStroke(2F));
			renderer.setSeriesStroke(2, new BasicStroke(2F));
			renderer.setSeriesStroke(3, new BasicStroke(2F));
		}
		xyItemRenderer.setSeriesPaint(0, new Color(255,0,128));
		xyItemRenderer.setSeriesPaint(1, new Color(0, 0, 255));
		xyItemRenderer.setSeriesPaint(2, new Color(124,130,96));
		xyItemRenderer.setSeriesPaint(3, new Color(128,0,128));

		DateAxis axis = (DateAxis) plot.getDomainAxis();
		axis.setDateFormatOverride(new SimpleDateFormat("MM/dd/yy"));
		axis.setTickMarksVisible(false);
		plot.getRenderer().setBaseItemLabelGenerator(new StandardXYItemLabelGenerator());
		plot.getRenderer().setBaseItemLabelsVisible(false);
		plot.getRenderer().setBaseItemLabelFont(new Font("Arial", Font.PLAIN, 8));
		plot.setNoDataMessage("No Message!");
		plot.setNoDataMessageFont(new Font("Arial", Font.PLAIN, 20));
		ValueAxis y_range = plot.getRangeAxis();
		y_range.setAutoRange(true);
		y_range.setAutoRangeMinimumSize(0.05);
		y_range.setRange(0, 0.25);
		plot.setRangeAxis(y_range);
		return chart;
	}
/**
	 * 
	 * @param doc The pdf file location for outputting
	 * @param title The chart title
	 * @param fileInput The Excel file location for inputting
	 */
	public static void writeChartToPDF(Document doc, String title, File fileInput) {

		XLSXReader xlsxReader = new XLSXReader();
		List<Map<String, String>> list = xlsxReader.readerToMAP(fileInput, 1,
				Integer.parseInt("100"));
		try {

			JFreeChart chart = createTimeSeriesLineChart(title, list);
			BufferedImage image1 = chart.createBufferedImage(800, 600);
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			ImageIO.write(image1, "png", baos);
			Image iTextImages = Image.getInstance(baos.toByteArray());
			iTextImages.setSpacingBefore(50);
			iTextImages.scaleAbsolute(520, 390);
			iTextImages.setPaddingTop(20);
			doc.add(iTextImages);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

如果报出读取文件过大的异常,可以尝试在POI读取Excel之前调用:
ZipSecureFile.setMinInflateRatio(-1.0d);


总结

例如:以上就是今天要讲的内容,本文仅仅简单介绍了JfreeChart的使用,之后可能再会说说PdfPTable遇到的一些坑。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值