使用Aspose.Words for Java 可以导出复杂WORD PDF HTML 多种数据格式
官方下载地址: http://www.aspose.com/java/word-component.aspx
第二部写一个具体的实现类
!!!因为Aspose.Words for Java不支持HashMap的数据格式,需要我们自己实现
好在它提供了IMailMergeDataSource接口
这样我们就把数据填充好了。接下来就是导出了
官方下载地址: http://www.aspose.com/java/word-component.aspx
我所用的版本是Aspose.Words.jdk16.jar
先看效果图
1-对数据行的导出,分别是PDF与WORD格式
[size=large]
使用该组件一共分为4个步骤
1-定义模板
2-加载模板
3-填充数据
4-设置导出格式并导出
接下来我们按照以上4个步骤进行报表的导出
首先定义模板(可以再附件中下载)这里只介绍最后一个个人简历的模板
一个普通的自定义word就可以
«TableStart:Employees»
«TableEnd:Employees»
这一对标记代表一个数据单元 Employees 是可以自定义的 填充数据源时要对应上
其他的就好理解了 比如«FirstName» 就是数据源中的属性
接下来开始我们的导出之旅吧!!!!
第一步定义一个导出的抽象类
- package com.epkj.words;
- import org.springframework.stereotype.Component;
- import com.aspose.words.Document;
- @Component("ProcessWord")
- public abstract class ProcessWord {
- public abstract Document execute(String templatePath) throws Exception;
- }
第二部写一个具体的实现类
- package com.epkj.words;
- import java.io.FileInputStream;
- import java.io.IOException;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import org.springframework.stereotype.Component;
- import com.aspose.words.Document;
- /**
- * 带图片的导出
- */
- @Component("EmployeesReportDemo")
- public class EmployeesReportDemo extends ProcessWord {
- @Override
- public Document execute(String templatePath) throws Exception {
- //1 读取模板
- Document doc = new Document(templatePath + "/" + "EmployeesReportDemo.doc");
- String imagePath = templatePath + "/" + "employees.jpg";
- //2 填充数据源
- doc.getMailMerge().executeWithRegions(new MapMailMergeDataSource(getMapList(imagePath), "Employees"));
- return doc;
- }
- private List<Map<String, Object>> getMapList(String imagePath) throws IOException {
- List<Map<String, Object>> dataList = new ArrayList<Map<String,Object>>();
- //读取一个二进制图片
- FileInputStream fis = new FileInputStream(imagePath);
- byte[] image = new byte[fis.available()];
- fis.read(image);
- fis.close();
- for (int i = 0; i < 20; i++) {
- Map<String, Object> record = new HashMap<String, Object>();
- //这里的key要与模板中的<<xxxxx>>对应
- record.put("FirstName", "欧阳");
- record.put("LastName", "夏丹");
- record.put("Title", "个人简历导出Word PDF");
- record.put("Address", "中国 北京市 东城区");
- record.put("City", "北京");
- record.put("Country", "辽宁沈阳");
- //二进制数据
- record.put("PhotoBLOB", image);
- dataList.add(record);
- }
- return dataList;
- }
- }
!!!因为Aspose.Words for Java不支持HashMap的数据格式,需要我们自己实现
好在它提供了IMailMergeDataSource接口
- package com.epkj.words;
- import java.util.ArrayList;
- import java.util.List;
- import java.util.Map;
- import com.aspose.words.IMailMergeDataSource;
- /**
- * 实现对HashMap的支持
- */
- public class MapMailMergeDataSource implements IMailMergeDataSource {
- private List<Map<String, Object>> dataList;
- private int index;
- //word模板中的«TableStart:tableName»«TableEnd:tableName»对应
- private String tableName = null;
- /**
- * @param dataList 数据集
- * @param tableName 与模板中的Name对应
- */
- public MapMailMergeDataSource(List<Map<String, Object>> dataList, String tableName) {
- this.dataList = dataList;
- this.tableName = tableName;
- index = -1;
- }
- /**
- * @param data 单个数据集
- * @param tableName 与模板中的Name对应
- */
- public MapMailMergeDataSource(Map<String, Object> data, String tableName) {
- if(this.dataList == null) {
- this.dataList = new ArrayList<Map<String,Object>>();
- this.dataList.add(data);
- }
- this.tableName = tableName;
- index = -1;
- }
- /**
- * 获取结果集总数
- * @return
- */
- private int getCount() {
- return this.dataList.size();
- }
- @Override
- public IMailMergeDataSource getChildDataSource(String arg0)
- throws Exception {
- return null;
- }
- @Override
- public String getTableName() throws Exception {
- return this.tableName;
- }
- /**
- * 实现接口
- * 获取当前index指向数据行的数据
- * 将数据存入args数组中即可
- * @return ***返回false则不绑定数据***
- */
- @Override
- public boolean getValue(String key, Object[] args) throws Exception {
- if(index < 0 || index >= this.getCount()) {
- return false;
- }
- if(args != null && args.length > 0) {
- args[0] = this.dataList.get(index).get(key);
- return true;
- } else {
- return false;
- }
- }
- /**
- * 实现接口
- * 判断是否还有下一条记录
- */
- @Override
- public boolean moveNext() throws Exception {
- index += 1;
- if(index >= this.getCount())
- {
- return false;
- }
- return true;
- }
- }
这样我们就把数据填充好了。接下来就是导出了
- package com.epkj.words;
- import javax.servlet.ServletContext;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import org.springframework.stereotype.Controller;
- import org.springframework.web.bind.annotation.RequestMapping;
- import org.springframework.web.context.WebApplicationContext;
- import org.springframework.web.context.support.WebApplicationContextUtils;
- import com.aspose.words.Document;
- import com.aspose.words.SaveFormat;
- /**
- * 所有导出功能由该类完成
- */
- @Controller
- @RequestMapping("/DemoBaseController.do")
- public class DemoBaseController {
- @RequestMapping(params = "method=exportDoc")
- public Object exportDoc(HttpServletRequest request, HttpServletResponse response) {
- ServletContext sc = request.getSession().getServletContext();
- //加载对应的模板
- String command = request.getParameter("command");
- //下载的文件名
- String docName = request.getParameter("docName");
- if(docName == null) {
- docName = System.currentTimeMillis() + "";
- }
- //返回到客户端的格式(DOC DOCX PDF)
- String formatType = request.getParameter("formatType");
- if(formatType == null) {
- formatType = "DOCX";
- }
- ProcessWord pw = getProcessWordByName(command, sc);
- try {
- Document doc = pw.execute(sc.getRealPath("/Designer"));
- sendToBrowser(doc, docName, formatType, true, response);
- response.flushBuffer();
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- return null;
- }
- public WebApplicationContext getWebApplicationContext(ServletContext sc) {
- return WebApplicationContextUtils.getRequiredWebApplicationContext(sc);
- }
- private ProcessWord getProcessWordByName(String name, ServletContext sc) {
- return (ProcessWord) this.getWebApplicationContext(sc).getBean(name);
- }
- /**
- * 向客户端发送数据
- * @param doc com.aspose.words.Document
- * @param docName 返回客户端的word文件名
- * @param formatType DOC 或者 DOCX
- * @param openNewWindow 在线打开或者下载
- * @param response
- * @throws Exception
- */
- private void sendToBrowser(Document doc, String docName, String formatType,
- boolean openNewWindow, HttpServletResponse response)
- throws Exception {
- String extension = formatType;
- if (formatType.equals("WML") || formatType.equals("FOPC"))
- extension = "XML";
- String fileName = docName + "." + extension;
- if (openNewWindow)
- response.setHeader("content-disposition", "attachment; filename="
- + fileName);
- else
- response.addHeader("content-disposition", "inline; filename="
- + fileName);
- if ("DOC".equals(formatType)) {
- response.setContentType("application/msword");
- doc.save(response.getOutputStream(), SaveFormat.DOC);
- } else if ("DOCX".equals(formatType)) {
- response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");
- doc.save(response.getOutputStream(), SaveFormat.DOCX);
- } else if ("PDF".equals(formatType)) {
- response.setContentType("application/pdf");
- doc.save(response.getOutputStream(), SaveFormat.PDF);
- }
- }
- }