在上一篇博客中,演示的是如何创建doc文档,并且插入段落,设定段落的格式,但是在实际应用中,除了文字描述我们可能还需要将某一些数据做成图表的形式在文档中展现。我研究了很久,发现如果要生成图片要用到XSSFDocument,这个是用来操作.xlsx文件,生成的图片怎么放到word中,没有找到合适的方法。所以我们使用JFreeChart报表控件来生成图像文件,然后存入到word中。本篇将演示两个例子,柱状图与折线图。首先看一下Maven依赖:在上一篇博客的基础上增加了JFreeChart依赖包.
<dependencies>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.0.1</version>
</dependency>
<dependency>
<groupId>org.jfree</groupId>
<artifactId>jfreechart</artifactId>
<version>1.5.0</version>
</dependency>
</dependencies>
然后就直接贴上代码了,具体见注释,注意修改代码中的文件路径。
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.util.Units;
import org.apache.poi.xwpf.usermodel.ParagraphAlignment;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.StandardChartTheme;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.util.ExportUtils;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.data.xy.XYSeries;
import org.jfree.data.xy.XYSeriesCollection;
import java.awt.*;
import java.io.*;
public class XDDFChartTest {
public static void main(String[] args) throws IOException, InvalidFormatException {
//设置JFreeChart主题,不设置会出现中文乱码情况
setTheme();
//柱状图演示
KeyValueBarTest();
//XY折线图演示
XYSeriesLineTest();
}
public static void XYSeriesLineTest() throws IOException, InvalidFormatException {
XWPFDocument doc=new XWPFDocument();
//创建数据源 y=x^2的数据
XYSeries series=new XYSeries("y=x^2");
for (int x = -100; x < 100; x++) {
int y = x*x;
series.add(x, y);
}
XYSeriesCollection collection=new XYSeriesCollection();
collection.addSeries(series);
//生成图形
JFreeChart xyLineChart = ChartFactory.createXYLineChart("y=x^2", "x", "y", collection, PlotOrientation.VERTICAL, true, false, false);
String path="D:\\MyData\\Desktop\\XYLineChart.jpeg";
String wPath="D:\\MyData\\Desktop\\XYlineChart.docx";
SaveDoc(wPath,path,xyLineChart,doc);
}
public static void KeyValueBarTest() throws IOException, InvalidFormatException {
XWPFDocument doc=new XWPFDocument();
DefaultCategoryDataset dataset = new DefaultCategoryDataset( );
dataset.addValue(123,"2018季度销售额","春季");
dataset.addValue(201,"2018季度销售额","夏季");
dataset.addValue(87,"2018季度销售额","秋季");
dataset.addValue(10,"2018季度销售额","冬季");
JFreeChart x = ChartFactory.createBarChart("y=f(x)", "x", "f(x)", dataset, PlotOrientation.VERTICAL,true,false,false );
String path="D:\\MyData\\Desktop\\barChart.jpeg";
String wPath="D:\\MyData\\Desktop\\barChart.docx";
SaveDoc(wPath,path,x,doc);
}
//保存图形到word文档中,这里是先生成image文件,然后又用输入流将文件导入,感觉很傻,
//如果您有更好的方法,请在评论区留言
private static void SaveDoc(String wpath, String path, JFreeChart chart, XWPFDocument doc) throws IOException, InvalidFormatException {
File chartFile = new File(path);
if(chartFile.exists())chartFile.delete();
ExportUtils.writeAsJPEG(chart,400,400,chartFile);
InputStream is=new FileInputStream(chartFile);
XWPFParagraph paragraph = doc.createParagraph();
paragraph.setAlignment(ParagraphAlignment.CENTER);
paragraph.setSpacingBetween(1.5);
XWPFRun run = paragraph.createRun();
run.addBreak();
run.addPicture(is, XWPFDocument.PICTURE_TYPE_JPEG, "LineChart.jpeg", Units.toEMU(400), Units.toEMU(400));
OutputStream os1=new FileOutputStream(new File(wpath));
doc.write(os1);
}
public static void setTheme(){
StandardChartTheme standardChartTheme=new StandardChartTheme("CN");
//设置标题字体
standardChartTheme.setExtraLargeFont(new Font("隶书",Font.BOLD,20));
//设置图例的字体
standardChartTheme.setRegularFont(new Font("宋书",Font.PLAIN,15));
//设置轴向的字体
standardChartTheme.setLargeFont(new Font("宋书",Font.PLAIN,15));
//应用主题样式
ChartFactory.setChartTheme(standardChartTheme);
}
}
效果图: