使用Aspose.Words for Java完成复杂Word与PDF的导出

使用Aspose.Words for Java完成复杂Word与PDF的导出

使用Aspose.Words for Java 可以导出复杂WORD PDF HTML 多种数据格式
官方下载地址:
http://www.aspose.com/java/word-component.aspx
我所用的版本是Aspose.Words.jdk16.jar


先看效果图


1-对数据行的导出,分别是PDF与WORD格式










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








[size=large]
使用该组件一共分为4个步骤
1-定义模板
2-加载模板
3-填充数据
4-设置导出格式并导出
接下来我们按照以上4个步骤进行报表的导出

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

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

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



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

第一步定义一个导出的抽象类
Java代码
  1. package com.epkj.words;   
  2.   
  3. import org.springframework.stereotype.Component;   
  4.   
  5. import com.aspose.words.Document;   
  6.   
  7. @Component("ProcessWord")   
  8. public abstract class ProcessWord {   
  9.   
  10.     public abstract Document execute(String templatePath) throws Exception;   
  11.        
  12. }  
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;
	
}

第二部写一个具体的实现类
Java代码
  1. package com.epkj.words;   
  2.   
  3. import java.io.FileInputStream;   
  4. import java.io.IOException;   
  5. import java.util.ArrayList;   
  6. import java.util.HashMap;   
  7. import java.util.List;   
  8. import java.util.Map;   
  9.   
  10. import org.springframework.stereotype.Component;   
  11.   
  12. import com.aspose.words.Document;   
  13.   
  14. /**  
  15.  * 带图片的导出  
  16.  */  
  17. @Component("EmployeesReportDemo")   
  18. public class EmployeesReportDemo extends ProcessWord {   
  19.   
  20.     @Override  
  21.     public Document execute(String templatePath) throws Exception {   
  22. //1 读取模板   
  23.         Document doc = new Document(templatePath + "/" + "EmployeesReportDemo.doc");   
  24.         String imagePath = templatePath + "/" + "employees.jpg";   
  25. //2 填充数据源   
  26.         doc.getMailMerge().executeWithRegions(new MapMailMergeDataSource(getMapList(imagePath), "Employees"));   
  27.         return doc;   
  28.     }   
  29.        
  30.     private List<Map<String, Object>> getMapList(String imagePath) throws IOException {   
  31.         List<Map<String, Object>> dataList = new ArrayList<Map<String,Object>>();   
  32.            
  33.         //读取一个二进制图片   
  34.         FileInputStream fis = new FileInputStream(imagePath);   
  35.         byte[] image = new byte[fis.available()];   
  36.         fis.read(image);   
  37.         fis.close();   
  38.            
  39.         for (int i = 0; i < 20; i++) {   
  40.             Map<String, Object> record = new HashMap<String, Object>();   
  41. //这里的key要与模板中的<<xxxxx>>对应   
  42.             record.put("FirstName""欧阳");   
  43.             record.put("LastName""夏丹");   
  44.             record.put("Title""个人简历导出Word PDF");   
  45.             record.put("Address""中国 北京市 东城区");   
  46.             record.put("City""北京");   
  47.             record.put("Country""辽宁沈阳");   
  48.             //二进制数据   
  49.             record.put("PhotoBLOB", image);   
  50.             dataList.add(record);   
  51.         }   
  52.         return dataList;   
  53.     }   
  54.        
  55. }  
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接口
Java代码
  1. package com.epkj.words;   
  2.   
  3. import java.util.ArrayList;   
  4. import java.util.List;   
  5. import java.util.Map;   
  6.   
  7. import com.aspose.words.IMailMergeDataSource;   
  8.   
  9. /**  
  10.  * 实现对HashMap的支持  
  11.  */  
  12. public class MapMailMergeDataSource implements IMailMergeDataSource {   
  13.   
  14.     private List<Map<String, Object>> dataList;   
  15.        
  16.     private int index;   
  17.        
  18.     //word模板中的«TableStart:tableName»«TableEnd:tableName»对应   
  19.     private String tableName = null;   
  20.        
  21.     /**  
  22.      * @param dataList 数据集  
  23.      * @param tableName 与模板中的Name对应  
  24.      */  
  25.     public MapMailMergeDataSource(List<Map<String, Object>> dataList, String tableName) {   
  26.         this.dataList = dataList;   
  27.         this.tableName = tableName;   
  28.         index = -1;   
  29.     }   
  30.        
  31.     /**  
  32.      * @param data 单个数据集  
  33.      * @param tableName 与模板中的Name对应  
  34.      */  
  35.     public MapMailMergeDataSource(Map<String, Object> data, String tableName) {   
  36.         if(this.dataList == null) {   
  37.             this.dataList = new ArrayList<Map<String,Object>>();   
  38.             this.dataList.add(data);   
  39.         }   
  40.         this.tableName = tableName;   
  41.         index = -1;   
  42.     }   
  43.        
  44.     /**  
  45.      * 获取结果集总数  
  46.      * @return  
  47.      */  
  48.     private int getCount() {   
  49.         return this.dataList.size();   
  50.     }   
  51.        
  52.     @Override  
  53.     public IMailMergeDataSource getChildDataSource(String arg0)   
  54.             throws Exception {   
  55.         return null;   
  56.     }   
  57.   
  58.     @Override  
  59.     public String getTableName() throws Exception {   
  60.         return this.tableName;   
  61.     }   
  62.   
  63.     /**  
  64.      * 实现接口  
  65.      * 获取当前index指向数据行的数据  
  66.      * 将数据存入args数组中即可  
  67.      * @return ***返回false则不绑定数据***  
  68.      */  
  69.     @Override  
  70.     public boolean getValue(String key, Object[] args) throws Exception {   
  71.         if(index < 0 || index >= this.getCount()) {   
  72.             return false;   
  73.         }   
  74.         if(args != null && args.length > 0) {   
  75.             args[0] = this.dataList.get(index).get(key);   
  76.             return true;   
  77.         } else {   
  78.             return false;   
  79.         }   
  80.     }   
  81.   
  82.     /**  
  83.      * 实现接口  
  84.      * 判断是否还有下一条记录  
  85.      */  
  86.     @Override  
  87.     public boolean moveNext() throws Exception {   
  88.         index += 1;   
  89.         if(index >= this.getCount())   
  90.         {   
  91.             return false;   
  92.         }   
  93.         return true;   
  94.     }   
  95.   
  96. }  
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;
	}

}



这样我们就把数据填充好了。接下来就是导出了
Java代码
  1. package com.epkj.words;   
  2.   
  3. import javax.servlet.ServletContext;   
  4. import javax.servlet.http.HttpServletRequest;   
  5. import javax.servlet.http.HttpServletResponse;   
  6.   
  7. import org.springframework.stereotype.Controller;   
  8. import org.springframework.web.bind.annotation.RequestMapping;   
  9. import org.springframework.web.context.WebApplicationContext;   
  10. import org.springframework.web.context.support.WebApplicationContextUtils;   
  11.   
  12. import com.aspose.words.Document;   
  13. import com.aspose.words.SaveFormat;   
  14.   
  15. /**  
  16.  * 所有导出功能由该类完成  
  17.  */  
  18. @Controller  
  19. @RequestMapping("/DemoBaseController.do")   
  20. public class DemoBaseController {   
  21.   
  22.     @RequestMapping(params = "method=exportDoc")   
  23.     public Object exportDoc(HttpServletRequest request, HttpServletResponse response) {   
  24.            
  25.         ServletContext sc = request.getSession().getServletContext();   
  26.            
  27.         //加载对应的模板   
  28.         String command = request.getParameter("command");   
  29.            
  30.         //下载的文件名   
  31.         String docName = request.getParameter("docName");   
  32.            
  33.         if(docName == null) {   
  34.             docName = System.currentTimeMillis() + "";   
  35.         }   
  36.            
  37.         //返回到客户端的格式(DOC DOCX PDF)   
  38.         String formatType = request.getParameter("formatType");   
  39.            
  40.         if(formatType == null) {   
  41.             formatType = "DOCX";   
  42.         }   
  43.            
  44.         ProcessWord pw = getProcessWordByName(command, sc);   
  45.            
  46.         try {   
  47.             Document doc = pw.execute(sc.getRealPath("/Designer"));   
  48.             sendToBrowser(doc, docName, formatType, true, response);   
  49.             response.flushBuffer();   
  50.         } catch (Exception e) {   
  51.             throw new RuntimeException(e);   
  52.         }   
  53.         return null;   
  54.     }   
  55.        
  56.     public WebApplicationContext getWebApplicationContext(ServletContext sc) {   
  57.         return WebApplicationContextUtils.getRequiredWebApplicationContext(sc);   
  58.     }   
  59.        
  60.     private ProcessWord getProcessWordByName(String name, ServletContext sc) {   
  61.         return (ProcessWord) this.getWebApplicationContext(sc).getBean(name);   
  62.     }   
  63.        
  64.     /**  
  65.      * 向客户端发送数据  
  66.      * @param doc com.aspose.words.Document  
  67.      * @param docName 返回客户端的word文件名  
  68.      * @param formatType DOC 或者 DOCX  
  69.      * @param openNewWindow 在线打开或者下载  
  70.      * @param response  
  71.      * @throws Exception  
  72.      */  
  73.     private void sendToBrowser(Document doc, String docName, String formatType,   
  74.             boolean openNewWindow, HttpServletResponse response)   
  75.             throws Exception {   
  76.         String extension = formatType;   
  77.   
  78.         if (formatType.equals("WML") || formatType.equals("FOPC"))   
  79.             extension = "XML";   
  80.   
  81.         String fileName = docName + "." + extension;   
  82.   
  83.         if (openNewWindow)   
  84.             response.setHeader("content-disposition""attachment; filename="  
  85.                     + fileName);   
  86.         else  
  87.             response.addHeader("content-disposition""inline; filename="  
  88.                     + fileName);   
  89.   
  90.         if ("DOC".equals(formatType)) {   
  91.             response.setContentType("application/msword");   
  92.             doc.save(response.getOutputStream(), SaveFormat.DOC);   
  93.         } else if ("DOCX".equals(formatType)) {   
  94.             response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");   
  95.             doc.save(response.getOutputStream(), SaveFormat.DOCX);   
  96.         } else if ("PDF".equals(formatType)) {   
  97.             response.setContentType("application/pdf");   
  98.             doc.save(response.getOutputStream(), SaveFormat.PDF);   
  99.         }    
  100.     }   
  101.        
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值