jaspersoft studio实践 --实现网页版打印小票(模板一)

由于项目业务需要,需要开发一个打印票据的需求。于是前面找了一堆资料来简单学习了下,就开始自己动手开发起来了,下面直接细说。
首先小票模板的设计就用到了Jaspersoft Studio这个软件(如果需要可以联系我或者官网上能下载到: https://community.jaspersoft.com/community-download)。

1.模板设计。

在这里插入图片描述
设计模板的步骤就不一一细说了,前面转载的文章也有提到,可以去看看。直接上已经做好的模板,如下图:在这里插入图片描述
数据来源是 json数据源,先写一个json文件并且类型、名称要对应与之连接。
在这里插入图片描述
而两者连接需要xml文件,再新建一个xml文件。
在这里插入图片描述
**加粗样式**
最后进行连接匹配,如下图:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
最后将其生成的.jasper文件放到项目中去,如图:
在这里插入图片描述
在这里插入图片描述

2.工具类。

到此,模板就设计完成了,下面就是利用java代码进行赋值并且连接打印机打印了。
给出jasperReport的工具类,代码如下:

package com.yd.wb.report.jasperReport;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.jasperreports.engine.JRPrintPage;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.export.HtmlExporter;
import net.sf.jasperreports.engine.export.JRPdfExporter;
import net.sf.jasperreports.engine.export.ooxml.JRXlsxExporter;
import net.sf.jasperreports.engine.query.JsonQueryExecuterFactory;
import net.sf.jasperreports.engine.util.JRLoader;
import net.sf.jasperreports.export.SimpleExporterInput;
import net.sf.jasperreports.export.SimpleHtmlExporterOutput;
import net.sf.jasperreports.export.SimpleOutputStreamExporterOutput;
import net.sf.jasperreports.export.SimpleXlsxReportConfiguration;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ResourceLoader;
import org.springframework.stereotype.Component;

import util.JCDFJsonUtil;

/**
 * @Description 打印PDF格式报表的工具类
 * 使用步骤:
 * 1.通过spring mvc生成json格式的业务数据
 * 2.将上一步生成的json数据保存成文件(调用exportJasperReport时将ReportType设置成JSON)
 * 3.在Jaspersoft@Studio创建DataAdapter, 类型为JSON File, 将上一步生成的文件作为数据源
 * 4.在Jaspersoft@Studio创建Jasper Report
 * 5.将编译好的jasper复制到WEB-INF下的report目录下
 * 6.调整Controller将输出的ReportType调整成真实的类型, 运行输出
 * 注意: 
 * 	 在Jasper Report创建时一定要增加一个 SUBREPORT_DIR 用于存储子报表路径
 * 
 */
@Component
public class JasperResolver {
	private Logger logger = Logger.getLogger(JasperResolver.class);
	@Autowired
	private ResourceLoader resourceLoader;
	
	/**
	 * @Description 将JSON填充到JasperReport格式化输出
	 * @param data 单报表输出的数据 Map<String, Object>
	 * @param reportFileName 报表文件名
	 * @param reportType 报表类型
	 * @return void
	 * 
	 */
	public void exportJasperReport(Map<String, Object> data, String reportFileName, ReportType reportType, 
			HttpServletRequest request, HttpServletResponse response) throws Exception{
		List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
		list.add(data);
		exportJasperReport(list, reportFileName, reportType, request, response);
	}

	/**
	 * @Description 将JSON填充到JasperReport格式化输出, 支持连打, 每一个List下的Item为一个Report
	 * @param data 多报表输出 List<Map<String, Object>>
	 * @param reportFileName 报表文件名
	 * @param reportType 报表类型
	 * @return void
	 * 
	 */
	public void exportJasperReport(List<Map<String, Object>> data, String reportFileName, ReportType reportType, 
			HttpServletRequest request, HttpServletResponse response) throws Exception{
		exportJasperReport(data, "/WEB-INF/report/", reportFileName, reportType, request, response);
	}

	/**
	 * @Description 具体的实现方法
	 * @param data 要打印的数据
	 * @param reportPath jasper文件所在的路径
	 * @param reportFileName 报表文件名
	 * @param reportType 报表类型
	 * @return void
	 * 
	 */
	private void exportJasperReport(List<Map<String, Object>> data, String reportPath, String reportFileName, ReportType reportType, 
			HttpServletRequest request, HttpServletResponse response) throws Exception{
		OutputStream os = null;
		JasperPrint jasperPrint = null;
		try {
			//JSON直接输出
			if(reportType == ReportType.JSON){ 
				response.setContentType("text/html;charset=UTF-8");
				response.setHeader("Pragma", "no-cache");
				response.setHeader("Cache-Control", "no-cache, must-revalidate");
				response.setHeader("Pragma", "no-cache");
				try {
					response.getWriter().write(JCDFJsonUtil.fromObjctToJson(data, null));
					response.getWriter().flush();
					response.getWriter().close();
				} catch (IOException e) {
					e.printStackTrace();
				}
				return;
			}
			//获取页面输出流
			os = response.getOutputStream(); 
			//设置页面类型及编码
			response.setContentType(reportType.getMimeType() + "; charset=utf-8"); 
			//清除页面缓存
			response.setDateHeader("Expires", 0); 
			//设置文件名
			response.setHeader("Content-Disposition", "inline;filename=" + URLEncoder.encode(UUID.randomUUID() + reportType.getSuffix(), "utf-8"));
			
			JasperReport report = (JasperReport)JRLoader.loadObject(resourceLoader.getResource(reportPath + reportFileName + ".jasper").getInputStream());
			
			//创建HashMap来添加报表参数
			Map<String, Object> parameters = new HashMap<String, Object>();
			//添加标题参数, 确保密钥与JasPrar报表中命名参数的名称相同
			String classesPath = this.getClass().getClassLoader().getResource("").getPath();
			String servletContextRealPath = classesPath.substring(0, classesPath.lastIndexOf("WEB-INF"));
			parameters.put("SUBREPORT_DIR", servletContextRealPath + reportPath);
			
			for(Map<String, Object> item : data){
				String json = JCDFJsonUtil.fromObjctToJson(item, null);
				//将JSON字符串转换为字节数组,从JSON流创建JSON数据源
				ByteArrayInputStream jsonDataStream = new ByteArrayInputStream(json.getBytes("utf-8"));
				parameters.put(JsonQueryExecuterFactory.JSON_INPUT_STREAM, jsonDataStream);
				
				if(null == jasperPrint){
					jasperPrint = JasperFillManager.fillReport(report, parameters);
				} else { //连打
					JasperPrint jasperPrintTemp = JasperFillManager.fillReport(report, parameters);
					List<JRPrintPage> pages = jasperPrintTemp.getPages();
					for (JRPrintPage page : pages) {
						jasperPrint.addPage(page);
					}
				}
			}
			
			switch(reportType){
				case PDF:
					JRPdfExporter pdfExporter = new JRPdfExporter();
					pdfExporter.setExporterInput(new SimpleExporterInput(jasperPrint));
					pdfExporter.setExporterOutput(new SimpleOutputStreamExporterOutput(os));
					pdfExporter.exportReport();
					break;
					
				case XLSX:
					Map<String, String> dateFormats = new HashMap<String, String>();
					dateFormats.put("EEE, MMM d, yyyy", "ddd, mmm d, yyyy");
					
					JRXlsxExporter xlsxExporter = new JRXlsxExporter();
					SimpleXlsxReportConfiguration configuration = new SimpleXlsxReportConfiguration();
					xlsxExporter.setExporterInput(new SimpleExporterInput(jasperPrint));
					xlsxExporter.setExporterOutput(new SimpleOutputStreamExporterOutput(os));
					configuration.setDetectCellType(Boolean.TRUE);
					configuration.setFormatPatternsMap(dateFormats);
					xlsxExporter.setConfiguration(configuration);
					xlsxExporter.exportReport();
					break;
					
				default:
					HtmlExporter htmlExporter = new HtmlExporter();
					htmlExporter.setExporterInput(new SimpleExporterInput(jasperPrint));
					htmlExporter.setExporterOutput(new SimpleHtmlExporterOutput(os));
					htmlExporter.exportReport();
					break;
			}	 
			
			if(null != os){
				os.flush();
			}
		} finally {
			if(null != os){
				try {
					os.close();
				} catch (Exception e) {
					logger.error(e);
				}
				
			}
		}
		
	}
}
package com.yd.wb.report.jasperReport;

import java.util.HashMap;
import java.util.Map;

/**
 * @Description 打印PDF格式报表的类型的枚举类
 * 
 */
public enum ReportType {
	PDF(".pdf",1,"application/pdf"),
    XLSX(".xlsx",2,"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"),
    HTML(".html",4,"text/html"),
    JSON(".json",4,"application/json");
	
	/**后缀*/
	private String suffix;
	
	/**枚举值*/
	private int value;
	
	/**页面类型*/
	private String mimeType;
	
	private ReportType(String suffix, int value, String mimeType){
		this.suffix = suffix;
		this.value = value;
		this.mimeType = mimeType;
	}
	
	//在枚举类型上实现fromString方法
	private static final Map<String, ReportType> stringToEnum = new HashMap<String, ReportType>();
	
	static {
		//从常量名初始化映射到enum常量
		for(ReportType item : values()){
			stringToEnum.put(item.toString(), item);
		}
	}
	
	//返回字符串的BLAH,如果字符串无效,则为nul
	public static ReportType fromString(String name){
		return stringToEnum.get(name);
	}

	public String getSuffix() {
		return suffix;
	}

	public void setSuffix(String suffix) {
		this.suffix = suffix;
	}

	public int getValue() {
		return value;
	}

	public void setValue(int value) {
		this.value = value;
	}

	public String getMimeType() {
		return mimeType;
	}

	public void setMimeType(String mimeType) {
		this.mimeType = mimeType;
	}
	
}

3.java代码获取值

controller层代码:

……………………………………………………………有关别的项目的代码就不显示了。
@Autowired
	private JasperResolver jasperResolver;
    private static final String C_ACTION_PRINT = "printTickets";
	
	/**
	 * 打印小票
	 */
	@RequestMapping(value="/printTickets")
    public CIPResponseMsg print(HttpServletRequest request,HttpServletResponse response,String serial_no,String trans_doc_id,String gross_weight,String net_weight){
		CIPResponseMsg msg = new CIPResponseMsg();
		//String trans_doc_id = request.getParameter("trans_doc_id");
		//Integer gross_weight = Integer.parseInt(request.getParameter("gross_weight"));
		Integer grossWeight = Integer.parseInt(gross_weight);
    	try {
    		   /*1、模板一:网点车未过磅小票。
    		                         网点车未过磅判断逻辑:【毛重KG】字段为0,发车凭证300开头*/
    		if(grossWeight == 0 && trans_doc_id.startsWith("300")){
    		   List<Map<String, Object>> data = dataService.queryData(serial_no);
			   jasperResolver.exportJasperReport(data, "TICKETS_NETPOINT_CARS1", ReportType.PDF, request, response);
    		}else if(grossWeight > 0 && trans_doc_id.startsWith("300")){
    			/*2、模板二:网点车已过磅小票。
                                                           网点车车已过磅判断逻辑:【毛重KG】字段为大于0,发车凭证300开头*/
    		   List<Map<String, Object>> data = dataService.queryOverweight(serial_no);
 			   jasperResolver.exportJasperReport(data, "TICKETS_NETPOINT_CARS2", ReportType.PDF, request, response);
    		}else if(trans_doc_id.startsWith("68")){
    			/*3、模板三:网络车小票       网络车判断逻辑:发车凭证68开头。*/
    		   List<Map<String, Object>> data = dataService.query(serial_no,trans_doc_id,net_weight);
    		   jasperResolver.exportJasperReport(data, "TICKETS_NETPOINT_CARS3", ReportType.PDF, request, response);
    		}
    	} catch (CIPServiceException e) {
			CIPErrorCode error = e.getErrorCode();
			msg.errorCode = error.code;
			msg.msg = error.name;
		} catch (CIPDaoException e) {
			CIPErrorCode error = e.getErrorCode();
			msg.errorCode = error.code;
			msg.msg = error.name;
		} catch (CIPRuntimeException e) {
			CIPErrorCode error = e.getErrorCode();
			msg.errorCode = error.code;
			msg.msg = error.name;
		} catch (Exception e) {
			log.error(e);
		}
    	return msg;
    }

service层代码:

/**
	 * 打印
	 * 模板一:网点车未过磅小票。
	 */
	@Override
	public List<Map<String, Object>> queryData(String ids) {
		//定义一个list,封装结果集
		List<Map<String, Object>> list = new ArrayList<Map<String,Object>>();
		//将传过来的id字符串转成id数组
		String[] idArr = ids.split(",");
		for (String serial_no : idArr) {
			//定义一个paraMap,封装查询参数
			Map<String, Object> paraMap = new HashMap<String, Object>();
			paraMap.put("serial_no", serial_no);
			//定义一个data,封装结果
			Map<String, Object> data = new HashMap<String,Object>();
			
			//查询信息
			Map<String, Object> map = dataDao.queryData(paraMap);
			if(map != null){
				Set<Entry<String, Object>> entrySet = map.entrySet();
				for (Entry<String, Object> entry : entrySet) {
					data.put(entry.getKey(), entry.getValue());
				}
			}
			list.add(data);
		}
		
		return list;
	}

dao层代码:

/**
	 * 打印功能
	 */
	@Override
	public Map<String, Object> queryData(Map<String, Object> paraMap) {
		Map<String, Object> map = null;
		String sql = "SELECT b.com_name weight_site,DATE_FORMAT(create_time, '%Y-%m-%d %H:%i:%s') create_time,serial_no,b.com_name start_site_name,concat('(', a.start_site, ')') start_site,car_id,trans_doc_id,ifnull(c.emp_name,a.operator) operator,SYSDATE() FROM wb_busi_gross_weight a "
                     + " LEFT JOIN wb_base_com b ON a.weight_site = b.com_bm LEFT JOIN wb_base_emp c on a.operator = c.emp_id WHERE a.serial_no = ?";
		//Object[] obj = {trans_doc_id};
		Object serial_no = paraMap.get("serial_no");
		try {
			map = jdbcTemplate.queryForMap(sql,serial_no);
			return map;
		} catch (Exception e) {
			log.error(e);
			return map;
		}
	}

sql语句,注意:查询后的字段要求与json文件的key相对应。

SELECT
	b.com_name weight_site,
	DATE_FORMAT(
		create_time,
		'%Y-%m-%d %H:%i:%s'
	) create_time,
	serial_no,
	b.com_name start_site_name,
	concat('(', a.start_site, ')') start_site,
	car_id,
	trans_doc_id,
	ifnull(c.emp_name, '') operator,
	SYSDATE()
FROM
	wb_busi_gross_weight a
LEFT JOIN wb_base_com b ON a.weight_site = b.com_bm
LEFT JOIN wb_base_emp c ON a.operator = c.emp_id
WHERE
	a.serial_no = '?'

html页面部分代码:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
最后的效果如下图:在这里插入图片描述在这里插入图片描述

当然打印机驱动是我自己安装的,这个看公司用的什么打印机,这里我就不介绍打印机配置的步骤了。
仅此记录下来,欢迎各位大佬指教。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章