java web报表,jasperReport使用简介
转载请注明出处!!!
jasperReport使用简介
需求简介:java web需生成报表,然后打印出来。报表用的jasperReport,编辑报表的可视化工具用的iReport。其次,web的打印是个比较棘手的问题,网上有很多第三方控件,经过不懈努力,找到了不少控件,但是支持直接打印(不跳预览)的免费版好像没有,无奈,用java手写了一个打印控件。
- 控件实现的功能:自动使用客户端电脑的默认打印机打印出指定的文件。【直接打印(不展示预览)】。
- 可指定双面打印。
- 可执行文件。打开一次后自动设置成开机自启文件。
1.下载报表模板编辑器iReport
iReport下载地址。本人用的最新版本,就这也是2014年的了。
若你电脑的java环境是jdk8,则下载后应该会出现无法打开的情况。解决办法:
2.做模板
红框内的组件是常用的,也是此教程中涉及到的组件。
若 组件面板 没有的话可以在 窗口-->组件面板 中打开。
设置静态文本(static text)即模板中不用在程序中赋值的文本。如:标题、表格头等等。
设置程序中赋值的文本(text field)
需要遍历的数据,模板制作方式:
图片组件的添加
如果需要转为pdf,并且模板中涉及到中文,则需要设置下编码。
点击上方的preview按钮,即可将jrxml文件编译成jasper文件,如图。若无法出现下图所示,说明模板编译时出错,请认真检查!
若出现 null ,解决办法:
此时,与jrxml文件同级目录下回出现jasper文件。jrxml文件编译之后会产生jasper文件,类似于java文件编译后产生class文件。
3.java中操作jasperReport
java操作jasperReport所需jar包
其中pdf.freejar包为手动添加到本地maven的结果。教程点此
<!--java操作pdf start--><dependency><groupId>spire</groupId><artifactId>pdf.free</artifactId><version>2.2.2</version></dependency><!--java操作pdf end--><!-- jasperReports Start --><!-- 该包的作用完成ireport中Preview按扭功能。通过该包可以通过java来ireport生成摸班(.jrxml或.jasper)填充数据源并导出pdf,excel,html等格式文件 --><dependency><groupId>net.sf.jasperreports</groupId><artifactId>jasperreports</artifactId><version>6.0.0</version></dependency><dependency><!-- 生成pdf所依赖的包 --><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId><version>5.5.11</version></dependency><dependency><groupId>com.itextpdf</groupId><artifactId>itext-pdfa</artifactId><version>5.5.11</version></dependency><dependency><groupId>com.itextpdf</groupId><artifactId>itext-asian</artifactId><version>5.2.0</version></dependency><!--将.jrxml编译成.jasper.如果你不使用java编译,而使用ireport工具编译则无须导入该 包 --><dependency><groupId>org.codehaus.groovy</groupId><artifactId>groovy-all</artifactId><version>2.4.13</version></dependency><!-- jasperreports End -->
java操作jasperReport工具类
package com.jdkj.detectSystem.Util;import net.sf.jasperreports.engine.*;
import net.sf.jasperreports.engine.base.JRBaseReport;
import net.sf.jasperreports.engine.export.*;
import net.sf.jasperreports.engine.util.JRLoader;
import net.sf.jasperreports.j2ee.servlets.ImageServlet;import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.lang.reflect.Field;
import java.net.URLEncoder;
import java.sql.Connection;
import java.util.Map;/*** @Description: java操作jasperReport工具类* @Param:* @return:*/
@SuppressWarnings("deprecation")
public class JasperHelper {public static final String PRINT_TYPE = "print";public static final String PDF_TYPE = "pdf";public static final String EXCEL_TYPE = "excel";public static final String HTML_TYPE = "html";public static final String WORD_TYPE = "word";public static void prepareReport(JasperReport jasperReport, String type) {/** 如果导出的是excel,则需要去掉周围的margin*/if ("excel".equals(type)) {try {Field margin = JRBaseReport.class.getDeclaredField("leftMargin");margin.setAccessible(true);margin.setInt(jasperReport, 0);margin = JRBaseReport.class.getDeclaredField("topMargin");margin.setAccessible(true);margin.setInt(jasperReport, 0);margin = JRBaseReport.class.getDeclaredField("bottomMargin");margin.setAccessible(true);margin.setInt(jasperReport, 0);Field pageHeight = JRBaseReport.class.getDeclaredField("pageHeight");pageHeight.setAccessible(true);pageHeight.setInt(jasperReport, 2147483647);} catch (Exception exception) {}}}/*** 导出excel*/public static void exportExcel(JasperPrint jasperPrint, String defaultFilename, HttpServletRequest request,HttpServletResponse response) throws IOException, JRException {/** 设置头信息*/response.setContentType("application/vnd.ms-excel");String defaultname = null;if (defaultFilename.trim() != null && defaultFilename != null) {defaultname = defaultFilename + ".xls";} else {defaultname = "export.xls";}response.setHeader("Content-Disposition","attachment; filename=\"" + URLEncoder.encode(defaultname, "UTF-8") + "\"");ServletOutputStream ouputStream = response.getOutputStream();JRXlsExporter exporter = new JRXlsExporter();exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, ouputStream);exporter.setParameter(JRXlsExporterParameter.IS_REMOVE_EMPTY_SPACE_BETWEEN_ROWS, Boolean.TRUE); // 删除记录最下面的空行exporter.setParameter(JRXlsExporterParameter.IS_ONE_PAGE_PER_SHEET, Boolean.FALSE);// 删除多余的ColumnHeader//exporter.setParameter(JRXlsExporterParameter.IS_WHITE_PAGE_BACKGROUND, Boolean.FALSE);// 显示边框exporter.exportReport();ouputStream.flush();ouputStream.close();}public static enum DocType {PDF, HTML, XLS, XML, RTF}@SuppressWarnings("rawtypes")public static JRAbstractExporter getJRExporter(DocType docType) {JRAbstractExporter exporter = null;switch (docType) {case PDF:exporter = new JRPdfExporter();break;case HTML:exporter = new JRHtmlExporter();break;case XLS:exporter = new JExcelApiExporter();break;case XML:exporter = new JRXmlExporter();break;case RTF:exporter = new JRRtfExporter();break;}return exporter;}/*** 导出pdf,注意此处中文问题,* 这里应该详细说:主要在ireport里变下就行了* 1)在ireport的classpath中加入iTextAsian.jar 2)在ireport画jrxml时,看ireport最左边有个属性栏。* 下边的设置就在点字段的属性后出现。 pdf font name :STSong-Light ,pdf encoding :UniGB-UCS2-H*/private static void exportPdf(JasperPrint jasperPrint, String defaultFilename, HttpServletRequest request,HttpServletResponse response) throws IOException, JRException {response.setContentType("application/pdf");String defaultname = null;if (defaultFilename.trim() != null && defaultFilename != null) {defaultname = defaultFilename + ".pdf";} else {defaultname = "export.pdf";}String fileName = new String(defaultname.getBytes("GBK"), "ISO8859_1");response.setHeader("Content-disposition", "attachment; filename=" + fileName);ServletOutputStream ouputStream = response.getOutputStream();JasperExportManager.exportReportToPdfStream(jasperPrint, ouputStream);ouputStream.flush();ouputStream.close();}/*** @Description:* @Param: [defaultFilename 存储文件路径及名称, is 模板源文件,parameters map参数,conn 列表参数]* @Return: void* @Author: WQ* @Date: 2020/8/24*/public static void exportPdfFile(String defaultFilename, File is, Map<String, Object> parameters, JRDataSource conn) {try {JasperReport jasperReport = (JasperReport) JRLoader.loadObject(is);prepareReport(jasperReport, "pdf");JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, conn);JasperExportManager.exportReportToPdfFile(jasperPrint, defaultFilename);} catch (Exception e) {e.printStackTrace();}}/*** @Description: 将jrxml文件编译成jasper文件* @Param: [jrxmlPath, jasperPath]* @Return: java.lang.String 返回jasper文件路径* @Author: WQ* @Date: 2020/8/24*/public static String jrxmlToJasper(String jrxmlPath, String jasperPath) throws JRException, IOException {JasperCompileManager.compileReportToFile(jrxmlPath, jasperPath);return jasperPath;}/*** 导出html*/private static void exportHtml(JasperPrint jasperPrint, String defaultFilename, HttpServletRequest request,HttpServletResponse response) throws IOException, JRException {response.setContentType("text/html");ServletOutputStream ouputStream = response.getOutputStream();JRHtmlExporter exporter = new JRHtmlExporter();exporter.setParameter(JRHtmlExporterParameter.IS_USING_IMAGES_TO_ALIGN, Boolean.FALSE);exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);exporter.setParameter(JRExporterParameter.CHARACTER_ENCODING, "UTF-8");exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, ouputStream);// 设置图片文件存放路径,此路径为服务器上的绝对路径String imageDIR = request.getSession().getServletContext().getRealPath("/");exporter.setParameter(JRHtmlExporterParameter.IMAGES_DIR_NAME, imageDIR);// 设置图片请求URIString imageURI = request.getContextPath() + "/";exporter.setParameter(JRHtmlExporterParameter.IMAGES_URI, imageURI);// 设置导出图片到图片存放路径exporter.setParameter(JRHtmlExporterParameter.IS_USING_IMAGES_TO_ALIGN, Boolean.TRUE);exporter.setParameter(JRHtmlExporterParameter.IS_OUTPUT_IMAGES_TO_DIR, Boolean.TRUE);exporter.exportReport();ouputStream.flush();ouputStream.close();}/*** 导出word*/@SuppressWarnings("rawtypes")private static void exportWord(JasperPrint jasperPrint, String defaultFilename, HttpServletRequest request,HttpServletResponse response) throws JRException, IOException {response.setContentType("application/msword;charset=utf-8");String defaultname = null;if (defaultFilename.trim() != null && defaultFilename != null) {defaultname = defaultFilename + ".doc";} else {defaultname = "export.doc";}String fileName = new String(defaultname.getBytes("GBK"), "utf-8");response.setHeader("Content-disposition", "attachment; filename=" + fileName);JRExporter exporter = new JRRtfExporter();exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, response.getOutputStream());exporter.exportReport();}/*** 按照类型导出不同格式文件** @param type 文件类型* @param is jasper文件的来源* @param request* @param response* @param defaultFilename 默认的导出文件的名称*/public static void export(String type, String defaultFilename, File is, HttpServletRequest request,HttpServletResponse response, Map parameters, Connection conn) {try {JasperReport jasperReport = (JasperReport) JRLoader.loadObject(is);prepareReport(jasperReport, type);JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, conn);if (EXCEL_TYPE.equals(type)) {exportExcel(jasperPrint, defaultFilename, request, response);} else if (PDF_TYPE.equals(type)) {exportPdf(jasperPrint, defaultFilename, request, response);} else if (HTML_TYPE.equals(type)) {exportHtml(jasperPrint, defaultFilename, request, response);} else if (WORD_TYPE.equals(type)) {exportWord(jasperPrint, defaultFilename, request, response);}} catch (Exception e) {e.printStackTrace();}}public static void export(String type, String defaultFilename, File is, HttpServletRequest request,HttpServletResponse response, Map parameters, JRDataSource conn) {try {JasperReport jasperReport = (JasperReport) JRLoader.loadObject(is);prepareReport(jasperReport, type);JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, conn);if (EXCEL_TYPE.equals(type)) {exportExcel(jasperPrint, defaultFilename, request, response);} else if (PDF_TYPE.equals(type)) {exportPdf(jasperPrint, defaultFilename, request, response);} else if (HTML_TYPE.equals(type)) {exportHtml(jasperPrint, defaultFilename, request, response);} else if (WORD_TYPE.equals(type)) {exportWord(jasperPrint, defaultFilename, request, response);}} catch (Exception e) {e.printStackTrace();}}/*** 输出html静态页面,必须注入request和response** @throws JRException* @throws IOException*/public static void showHtml(String defaultFilename, String reportfile, HttpServletRequest request,HttpServletResponse response, Map parameters, JRDataSource conn) throws JRException, IOException {request.setCharacterEncoding("utf-8");response.setCharacterEncoding("utf-8");response.setContentType("text/html");JRAbstractExporter exporter = getJRExporter(DocType.HTML);JasperPrint jasperPrint = JasperFillManager.fillReport(reportfile, parameters, conn);request.getSession().setAttribute(ImageServlet.DEFAULT_JASPER_PRINT_SESSION_ATTRIBUTE, jasperPrint);PrintWriter out = response.getWriter();exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);exporter.setParameter(JRExporterParameter.OUTPUT_WRITER, out);exporter.setParameter(JRHtmlExporterParameter.IS_USING_IMAGES_TO_ALIGN, Boolean.FALSE);// 设置图片文件存放路径,此路径为服务器上的绝对路径String imageDIR = request.getSession().getServletContext().getRealPath("/");exporter.setParameter(JRHtmlExporterParameter.IMAGES_DIR_NAME, imageDIR);// 设置图片请求URIString imageURI = request.getContextPath() + "/";exporter.setParameter(JRHtmlExporterParameter.IMAGES_URI, imageURI);// 设置导出图片到图片存放路径exporter.setParameter(JRHtmlExporterParameter.IS_USING_IMAGES_TO_ALIGN, Boolean.TRUE);exporter.setParameter(JRHtmlExporterParameter.IS_OUTPUT_IMAGES_TO_DIR, Boolean.TRUE);exporter.exportReport();out.flush();}public static void showHtml(String defaultFilename, String reportfile, HttpServletRequest request,HttpServletResponse response, Map parameters, Connection conn) throws JRException, IOException {request.setCharacterEncoding("utf-8");response.setCharacterEncoding("utf-8");response.setContentType("text/html");JRAbstractExporter exporter = getJRExporter(DocType.HTML);JasperPrint jasperPrint = JasperFillManager.fillReport(reportfile, parameters, conn);request.getSession().setAttribute(ImageServlet.DEFAULT_JASPER_PRINT_SESSION_ATTRIBUTE, jasperPrint);PrintWriter out = response.getWriter();exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);exporter.setParameter(JRExporterParameter.OUTPUT_WRITER, out);exporter.setParameter(JRHtmlExporterParameter.IS_USING_IMAGES_TO_ALIGN, Boolean.FALSE);// 设置图片文件存放路径,此路径为服务器上的绝对路径String imageDIR = request.getSession().getServletContext().getRealPath("/");exporter.setParameter(JRHtmlExporterParameter.IMAGES_DIR_NAME, imageDIR);// 设置图片请求URIString imageURI = request.getContextPath() + "/";exporter.setParameter(JRHtmlExporterParameter.IMAGES_URI, imageURI);// 设置导出图片到图片存放路径exporter.setParameter(JRHtmlExporterParameter.IS_USING_IMAGES_TO_ALIGN, Boolean.TRUE);exporter.setParameter(JRHtmlExporterParameter.IS_OUTPUT_IMAGES_TO_DIR, Boolean.TRUE);exporter.exportReport();out.flush();}@SuppressWarnings({"rawtypes", "unchecked"})public static void showPdf(String defaultFilename, String reportfile, HttpServletRequest request,HttpServletResponse response, Map parameters, JRDataSource conn) throws JRException, IOException {request.setCharacterEncoding("utf-8");response.setCharacterEncoding("utf-8");response.setContentType("text/html");response.setContentType("application/pdf");JRAbstractExporter exporter = getJRExporter(DocType.PDF);JasperPrint jasperPrint = JasperFillManager.fillReport(reportfile, parameters, conn);request.getSession().setAttribute(ImageServlet.DEFAULT_JASPER_PRINT_SESSION_ATTRIBUTE, jasperPrint);OutputStream out = response.getOutputStream();exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, out);exporter.exportReport();out.flush();}@SuppressWarnings({"rawtypes", "unchecked"})public static void showPdf(String defaultFilename, String reportfile, HttpServletRequest request,HttpServletResponse response, Map parameters, Connection conn) throws JRException, IOException {request.setCharacterEncoding("utf-8");response.setCharacterEncoding("utf-8");response.setContentType("text/html");response.setContentType("application/pdf");JRAbstractExporter exporter = getJRExporter(DocType.PDF);JasperPrint jasperPrint = JasperFillManager.fillReport(reportfile, parameters, conn);request.getSession().setAttribute(ImageServlet.DEFAULT_JASPER_PRINT_SESSION_ATTRIBUTE, jasperPrint);OutputStream out = response.getOutputStream();exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, out);exporter.exportReport();out.flush();}}
实际操作
项目结构:
核心操作类:
package com.wq.jasperReportDemo.service.impl;import com.wq.jasperReportDemo.entity.UserDO;
import com.wq.jasperReportDemo.service.UserDOSercice;
import com.wq.jasperReportDemo.util.JasperHelper;
import lombok.SneakyThrows;
import net.sf.jasperreports.engine.JRDataSource;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import org.springframework.stereotype.Service;import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;/*** @program: jasperReportDemo* @description: 用户操作业务层* @author: WQ**/
@Service
public class UserDOServiceImpl implements UserDOSercice {/*** @Description: 获取模板生成的pdf文件的路径* @Param: [jrxmlPath]* @return: java.lang.String* @Author: WQ* @Date: 2020/12/14*/@SneakyThrows@Overridepublic String getPdfPath(String jrxmlPath) {String imgPath = "C:\\Users\\19855\\Desktop\\jasperDemo\\img.jpg";String basePath = jrxmlPath.substring(0, jrxmlPath.length() - 7);//定义生成的pdf文件路径String pdfPath = basePath + ".pdf";//生成jasper文件路径String jasperPath = basePath + ".jasper";// jrxml文件编译成jasper文件JasperHelper.jrxmlToJasper(jrxmlPath, jasperPath);// 遍历数据渲染List<UserDO> list = new ArrayList<>();list.add(new UserDO("张三", "123"));list.add(new UserDO("李四", "456"));list.add(new UserDO("王五", "789"));//获取数据源JRDataSource jrDataSource = new JRBeanCollectionDataSource(list);// map数据渲染Map<String, Object> map = new HashMap<>();map.put("test", "测试字段");map.put("imgPath", imgPath);//图片也是传入图片的路径。传图片的base64字符串无法正常显示(本人测试过)//创建jasper文件File reportFile = new File(jasperPath);//调用工具类,导出pdf文件JasperHelper.exportPdfFile(pdfPath, reportFile, map, jrDataSource);return pdfPath;}
}
测试方法
@SpringBootTest
class JasperReportDemoApplicationTests {@Autowiredprivate UserDOSercice userDOSercice;@Testvoid contextLoads() {String pdfPath = userDOSercice.getPdfPath("C:\\Users\\19855\\Desktop\\jasperDemo\\report1.jrxml");System.out.println(pdfPath);}}
表格的边框啥的,都是可以加的,右击单个组件,选择padding and borders即可设置。
4.将pdf转为base64字符串并在前端打印出来
转base64工具类
package com.wq.jasperReportDemo.util;import org.apache.tomcat.util.codec.binary.Base64;import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;/*** @program: jasperReportDemo* @description:* @author: WQ* @create: 2020-12-14 15:34**/
public class FileUtil {/*** 文件转为base64字符串。filePath:文件路径*/public static String fileToBase64(String filePath) throws IOException {File file = new File(filePath);FileInputStream inputFile = new FileInputStream(file);byte[] buffer = new byte[(int) file.length()];inputFile.read(buffer);inputFile.close();byte[] bs = Base64.encodeBase64(buffer);return new String(bs);}}
5.前端接收,并调用打印控件打印出结果
控件有偿,需要私聊。
$.ajax({url: "http://localhost:5777/print",type: "post",data: data,//打开下方注释即双面打印//headers: {// 'Page-Type': 'DUPLEX'//},success: function (data) {layer.close(layer.index);if ("Success" == data) {layer.msg("报表已打印", {offset: "100px"});return true;} else {layer.msg("报表打印失败", {anim: 6, offset: "100px"});}return false;},error: function () {layer.close(layer.index);layer.msg("打印失败。连接打印机失败或控件未下载", {anim: 6, offset: "100px"});return false;}})