1、 java导出word的5种方式 https://blog.csdn.net/zi_wu_xian/article/details/80320520
2、jfreechart形成各种图 https://blog.csdn.net/chehec2010/article/details/81026789
3、jFreeChart 详细属性总结 https://blog.csdn.net/it_lihongmin/article/details/50469212
4、Java使用iText生成word文件的完美解决方案 https://blog.csdn.net/matinbell/article/details/73088948
5、使用iText在word文档中插入复杂的Table表格 https://blog.51cto.com/116833/1688695
6、ITEXT table的单元格边框设置 https://blog.csdn.net/cfup_less/article/details/82686426
需要把从数据库里查询出来的数据,从浏览器中导出到一个word文档,文档中包含折线图,饼状图,还有表格,文字等。
刚开始做的时候,觉得需求最大的问题在于能不能找到一种第三方的插件来实现在word 中画出折线图和饼状图, 后来通过从网上查找资料(见参考文章1),最后经过比较和权衡,决定使用第三方插件来先生成需要的折线图和饼状图,然后再向word中插入图片这种方式来实现。
使用 itext 和 itext-rtf 来操作word 文档,使用 jfreechart 来生成各种图表,下面列出了需要用到的jar maven依赖,其中itext 这两个jar包的版本要一直
org.jfree
jfreechart
1.0.19
com.lowagie
itext
2.1.7
jar
com.lowagie
itext-rtf
2.1.7
用到的代码基本上都是从网上找的,然后在根据自己的具体需求再去改造。(原谅我没有时间去具体细看),写这篇文章也是为了总结一下用到的知识,然后把东西汇总一下,方便以后再用。
这部分的代码主体主要参考了下面两篇文章,然后在这个的基础上进行了改造。
https://blog.csdn.net/chehec2010/article/details/81026789
https://blog.csdn.net/it_lihongmin/article/details/50469212
说一下改造过程中遇到的几个问题。
首先是 折线图刻度取值问题,因为要生成好几个折线图,而且几个折线图Y轴的取值范围差距也很大,不能写成一个定值。于是我就想了一种思路,所有值求和然后求平均数,再取一半的值。但是这样取到的值还有小数点,个位十位上都会有值,比如5.83,1453.5 等等这种,刻度线上的值还是整百整十这种比较好。然后我就又通过代码再取了一次值。思路是通过判断平均数的范围,然后给定一个基数,通过先除后乘这种操作来获得整值。下面是代码
int num = ((int)sum/2)/list.size();
int radix = 0;
if (num < 10) {
radix = 1;
} else if (num >= 10 && num < 100) {
radix = 10;
} else if (num >= 100 && num < 1000) {
radix = 100;
} else if (num >= 1000 && num < 10000) {
radix = 1000;
} else if (num >= 10000 && num < 100000) {
radix = 10000;
} else if (num >= 100000 && num < 1000000) {
radix = 100000;
} else if (num >= 1000000 && num < 10000000) {
radix = 1000000;
} else {
radix = 5000000;
}
tick= num / radix * radix;
再就是图例的乱码问题,找了好久,通过给图例上的字重新设置字体就能解决。
折线图:
// 横坐标
Font labelFont = new Font("仿宋", Font.TRUETYPE_FONT, 18);
CategoryAxis domainAxis = categoryplot.getDomainAxis();
domainAxis.setLabelFont(labelFont);// 轴标题
纵坐标
NumberAxis numberaxis = (NumberAxis) categoryplot.getRangeAxis();
numberaxis.setLabelFont(labelFont);
饼状图:
StandardChartTheme standardChartTheme=new StandardChartTheme("CN");
standardChartTheme.setRegularFont(new Font("宋书",Font.PLAIN,8));
ChartFactory.setChartTheme(standardChartTheme);
2、生成word文档
生成word文档时,主要参考了下面这篇文章
https://blog.csdn.net/matinbell/article/details/73088948
说一下碰到的几个问题
①生成文档的页边距控制不好,几乎把整个页面都占满了,后来通过查询资料,才知道 一些。
生成文档时 Document document = new Document(PageSize.A4,90,90,72,72); 可以设置左右的边界,90 和 72 基本都是通用的A4 纸的边距大小。
② word文档的字体怎么设置,大部分的网上教程都是直接让从本地的c盘的Windows字库中直接拿rtf 文件,但是我怎么试都不行,最后找到一种方式
RtfFont font =new RtfFont("仿 宋", 12, Font.NORMAL, Color.BLACK);
注意字体仿宋之间 有一个空格。
③因为是用浏览器导出的,所以要将字节流输出到 response 中返回给浏览器,使用 BufferedOutputStream 来包装了一下response的输出流,然后使用 RtfWriter2来写word 文档
OutputStream os = null;
response.reset();
response.setHeader("Content-Disposition", "attachment;filename="
+ new String((cityString+"检查结果"+simdf.format(new Date()) + ".doc").getBytes("gbk"),"iso8859-1"));
//response.setHeader("Content-Length", "" + file.length());
os = new BufferedOutputStream(response.getOutputStream());
response.setContentType("application/xml");
String path = "E:\\test\\";// word 文档中需要的图片 保存的路径
if(System.getProperty("os.name").toLowerCase().startsWith("linux")){
path ="/home/Tomcat/temp/";
File file = new File(path);
if (!file.exists()) {
file.mkdir();
}
}
DateFormat sFormat = new SimpleDateFormat("yyyy年MM月");
DateFormat sFormat1 = new SimpleDateFormat("yyyy-MM");
Document document = new Document(PageSize.A4,90,90,72,72);
//使用 rtf 来写word 文档
RtfWriter2.getInstance(document, os);
document.open();
④ 关于table 和 table 单元格的边框设置,可以参考下面两篇文章
https://blog.51cto.com/116833/1688695
https://blog.csdn.net/cfup_less/article/details/82686426