首页 > 代码库 > freemarker+Jfreechart生成Word文档(含图片)
freemarker+Jfreechart生成Word文档(含图片)
这几天再弄一个报表,要统计一些信息最终的部分展示结果如下:
基本工具freemarker,jfreechart
工程的部分结构如下
与生成Word有关的类主要有FreemarkerConfiguration和WordGenerator代码如下:
import com.bqs.ares.common.utils.CommonUtils; import freemarker.template.Configuration; import java.io.File; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Created by lenovo on 2016/9/27. */ public class FreemarkerConfiguration { private static Logger log = LoggerFactory.getLogger(FreemarkerConfiguration.class); private final static String filepath = "/freemarkerTemplate"; private static Configuration configuration=null; public static Configuration getConfiguration(){ if(configuration==null){ configuration=new Configuration(); try { configuration.setDirectoryForTemplateLoading(new File(CommonUtils.class.getResource(filepath).getFile())); }catch (Exception e){ log.error(e.getMessage()); } } return configuration; } }
import com.bqs.risk.dvp.common.PDFUtils.freemarker.FreemarkerConfiguration; import freemarker.template.Configuration; import freemarker.template.Template; import java.io.*; import java.util.Map; /** * Created by lenovo on 2016/10/9. */ public class WordGenerator { /** * Generate html string. * * @param template the name of freemarker teamlate. * @param variables the data of teamlate. * @return htmlStr * @throws Exception */ public static void generate(String template, Map<String,Object> variables, String htmlName) throws Exception{ String basePath=HtmlGenerator.class.getResource("/").getPath()+"/freemarkerTemplate/word/"; Configuration config = FreemarkerConfiguration.getConfiguration(); config.setDefaultEncoding("UTF-8"); Template tp = config.getTemplate(template); tp.setEncoding("UTF-8"); String htmlPath=basePath+htmlName+".doc"; File file = new File(htmlPath); if (!file.exists()) file.createNewFile(); Writer out = new BufferedWriter(new OutputStreamWriter( new FileOutputStream(file), "utf-8")); tp.process(variables, out); out.flush(); out.close(); } }
用jfreeChart生成折线图和饼图的代码如下:
import com.bqs.risk.dvp.common.InfoPoint; import org.jfree.chart.ChartFactory; import org.jfree.chart.ChartUtilities; import org.jfree.chart.JFreeChart; import org.jfree.chart.axis.NumberAxis; import org.jfree.chart.labels.ItemLabelAnchor; import org.jfree.chart.labels.ItemLabelPosition; import org.jfree.chart.labels.StandardCategoryItemLabelGenerator; import org.jfree.chart.labels.StandardPieSectionLabelGenerator; import org.jfree.chart.plot.CategoryPlot; import org.jfree.chart.plot.PiePlot; import org.jfree.chart.plot.PlotOrientation; import org.jfree.chart.renderer.category.LineAndShapeRenderer; import org.jfree.chart.title.TextTitle; import org.jfree.data.category.DefaultCategoryDataset; import org.jfree.data.general.DefaultPieDataset; import org.jfree.ui.TextAnchor; import java.awt.*; import java.io.File; import java.io.IOException; import java.text.NumberFormat; import java.util.*; import java.util.List; /** * Created by lenovo on 2016/9/28. */ public class JfreeChartUtils { private static Map<String,String> relationNameMap=null; private static DefaultCategoryDataset createDataset(int[] data) { DefaultCategoryDataset linedataset = new DefaultCategoryDataset(); // 曲线名称 String series = "时间-次数"; // series指的就是报表里的那条数据线 //因此 对数据线的相关设置就需要联系到serise //比如说setSeriesPaint 设置数据线的颜色 // 横轴名称(列名称) String[] time = new String[24]; for (int i = 0; i < 24; i++) { time[i] = i + ""; } //添加数据值 for (int i = 0; i < data.length; i++) { linedataset.addValue(data[i], //值 series, //哪条数据线 time[i]); // 对应的横轴 } return linedataset; } //生成事件统计图 public static String createChart(String eventTypevalue, int[] data, String imageName) { String returnImagePath = ""; Calendar calendar = Calendar.getInstance(); calendar.setTime(new Date()); calendar.add(Calendar.MONTH, -1); if (data =http://www.mamicode.com/= null || data.length <= 0) {>图片得到之后就是生成Word了,基本思路是先用Word做好模板,另存为xml,然后使用freemarker标签来替换,最后改成ftl文件就是模板,图片也只是替换那一大堆编码而已<w:pict> <w:binData w:name="wordml://03000003${imagePath_index}.png" xml:space="preserve">${imagePath}</w:binData> <v:shape id="_x0000_i1028" type="#_x0000_t75" style="width:440pt;height:440pt"> <v:imagedata src=http://www.mamicode.com/"wordml://03000003${imagePath_index}.png" o:title="6350.tmp"/>>但这里确实花了我很多时间,主要的坑如下:
1.freemarker标签的使用:尤其要注意是否为空的情况所以对于list还是map最好都加上这一句:
<#if infoLocationList??&&infoLocationList?size gt 0>是否存在,至于具体的循环遍历网上有不再赘述2.Word模板另存为xml文件时一定要注意,如果是较高一点的版本有两种格式xml和2003xml这个在处理图片时有较大差别,我是使用2003xml版本(高版本的在处理图片时有错误),它在处理的时候需要将图片转成base64码具体代码如下:
private String getImageStr(String imagePath) { String imgFile = imagePath; InputStream in = null; byte[] data = http://www.mamicode.com/null;>
3.多张图片插入时会遇到图片重复记得改name和src,从List中取出数据并且实现插入多张图片:<w:p wsp:rsidR="00C46D75" wsp:rsidRDefault="00C46D75" wsp:rsidP="00AC571C"/> <#if infoLocationList??&&infoLocationList?size gt 0> <w:p wsp:rsidR="0051625F" wsp:rsidRDefault="007F46BC" wsp:rsidP="00AC571C"> <w:r> <w:rPr> <w:rFonts w:hint="fareast"/> <wx:font wx:val="宋体"/> </w:rPr> <w:t>半年内手机号、身份证号、IP、GPS归属地信息分布</w:t> </w:r> </w:p> <#list infoLocationList as imagePath> <w:p wsp:rsidR="007F46BC" wsp:rsidRDefault="00E75FA4" wsp:rsidP="00AC571C"> <w:r> <w:tab/> </w:r> <w:r wsp:rsidR="00946545" wsp:rsidRPr="00946545"> <w:rPr> <w:noProof/> </w:rPr> <w:pict> <w:binData w:name="wordml://03000003${imagePath_index}.png" xml:space="preserve">${imagePath}</w:binData> <v:shape id="_x0000_i1028" type="#_x0000_t75" style="width:440pt;height:440pt"> <v:imagedata src=http://www.mamicode.com/"wordml://03000003${imagePath_index}.png" o:title="6350.tmp"/>> 4.如果模板太大转成的xml文件太大,看着是密密麻麻的一大片根本无法进一步处理,建议使用IDE进行代码格式化,想eclipse等等一般都可以,如果发现工具也无法格式化可以直接百度xml格式化,然后会有在线的工具5.有时候会遇到成功生成Word文档但是无法打开的情况,这时候可以根据错误提示用文本编辑工具来具体到哪一行去看看,如果遇到什么结束元素标签名称与开始标签名称不匹配多半是ftl中标签配对有问题(这个有时候即使没有改过也会出错,所以最好借助工具好好补齐标签)
6.乱码问题,主要是在Linux服务器上会出现,具体方法网上也有
以上是自己的一些经验之谈,更多是在整个流程以及自己所遇到的坑上,具体说每一步怎么处理网上都会有
freemarker+Jfreechart生成Word文档(含图片)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。