[size=xx-large]使用Aspose.Words for Java完成复杂Word与PDF的导出[/size]

[size=x-large]

使用Aspose.Words for Java 可以导出复杂WORD PDF HTML 多种数据格式

官方下载地址:[url]http://www.aspose.com/java/word-component.aspx[/url]

我所用的版本是Aspose.Words.jdk16.jar

[/size]


[size=large]先看效果图[/size]



[size=large]1-对数据行的导出,分别是PDF与WORD格式[/size]



[img]http://dl.iteye.com/upload/attachment/0083/9017/8a985bbe-3686-379e-8e6b-84863ad3bf45.jpg[/img]



[img]http://dl.iteye.com/upload/attachment/0083/9019/c7c6fa4c-d6ad-39ea-a726-5fb41e66b624.jpg[/img]



[size=large]2-对类似于个人简历的数据导出带图片,分别是PDF与WORD格式[/size]



[img]http://dl.iteye.com/upload/attachment/0083/9021/d640f516-7ce4-3e61-a4d9-3a4d5249df0e.jpg[/img]



[img]http://dl.iteye.com/upload/attachment/0083/9023/398c6a20-2837-342f-84df-73853d9a03f3.jpg[/img]



[size=large]

使用该组件一共分为4个步骤

1-定义模板

2-加载模板

3-填充数据

4-设置导出格式并导出

接下来我们按照以上4个步骤进行报表的导出


首先定义模板(可以再附件中下载)这里只介绍最后一个个人简历的模板

一个普通的自定义word就可以


«TableStart:Employees»

«TableEnd:Employees»

这一对标记代表一个数据单元 Employees 是可以自定义的 填充数据源时要对应上


其他的就好理解了 比如«FirstName» 就是数据源中的属性


[img]http://dl.iteye.com/upload/attachment/0083/9030/031eee08-c91e-36c7-ab71-1c3c46398ce5.jpg[/img]


接下来开始我们的导出之旅吧!!!!


第一步定义一个导出的抽象类

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);
}
}


}


[/size]



[size=xx-large]


由于源码比较大 所以没办法上传,所以有需要的朋友可以留下邮箱 我发给大家


[/size]