报表生成(POI,jquery.table2excel.js,Echarts)
最近公司要弄个报表相关的功能,话不多说,先上图
前一种是POI 生成的,后一种是Echarts生成的。报表我想大家都不陌生,基本上在公司业务中都会使用到。先说说POI,jquery.table2excel.js,Echarts这三种使用区别吧,本篇博客主要是使用上,如果只是像表格那样标准格式的导出的话,我想用table2挺好,只要把相关的js引入就可以使用,不用像poi那样生成模板,添加样式什么的。在网上都能搜到一大堆代码,当然了能不能用就不知道了。https://blog.csdn.net/weixin_36751895/article/details/79303854 这是相关链接;
POI虽然麻烦点,但是可以随着我们的心意基本上可以实现,就如第一种那种特殊样式的报表。
POI一般分为三个步骤:
1. 首先是POI 样式/模板的生成,你需要什么样式/模板,这是相关代码:
import java.io.*;
import java.text.SimpleDateFormat;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFClientAnchor;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFPatriarch;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.ss.usermodel.ClientAnchor.AnchorType;
import org.apache.poi.ss.util.CellRangeAddress;
import java.net.HttpURLConnection;
import java.net.URL;
import com.cn.jr.model.JrUser;
import com.cn.rz.model.JrUserOrders;
public class ExportExcel {
public void getValue(JrUser jrUser, JrUserOrders jrUserOrders, String imageUrl, OutputStream outData) {
if (jrUser == null || jrUserOrders == null) {
jrUser = new JrUser();
jrUserOrders = new JrUserOrders();
}
HSSFWorkbook workbook = new HSSFWorkbook();
try {
// 1.创建工作簿
// 1.1创建合并单元格对象
CellRangeAddress callRangeAddress = new CellRangeAddress(0, 2, 0, 7);// 起始行,结束行,起始列,结束列
CellRangeAddress callRangeAddress1 = new CellRangeAddress(3, 4, 0, 2);// 起始行,结束行,起始列,结束列
CellRangeAddress callRangeAddress20 = new CellRangeAddress(3, 4, 3, 7);// 起始行,结束行,起始列,结束列
CellRangeAddress callRangeAddress21 = new CellRangeAddress(5, 6, 0, 7);// 起始行,结束行,起始列,结束列
CellRangeAddress callRangeAddress22 = new CellRangeAddress(7, 8, 0, 2);// 起始行,结束行,起始列,结束列
CellRangeAddress callRangeAddress31 = new CellRangeAddress(7, 8, 3, 4);// 起始行,结束行,起始列,结束列
CellRangeAddress callRangeAddress32 = new CellRangeAddress(7, 8, 5, 7);// 起始行,结束行,起始列,结束列
CellRangeAddress callRangeAddress34 = new CellRangeAddress(9, 10, 0, 7);// 起始行,结束行,起始列,结束列
CellRangeAddress callRangeAddress35 = new CellRangeAddress(11, 12, 0, 2);// 起始行,结束行,起始列,结束列
CellRangeAddress callRangeAddress36 = new CellRangeAddress(11, 12, 3, 4);// 起始行,结束行,起始列,结束列
CellRangeAddress callRangeAddress37 = new CellRangeAddress(11, 12, 5, 7);// 起始行,结束行,起始列,结束列
CellRangeAddress callRangeAddress38 = new CellRangeAddress(13, 14, 0, 7);// 起始行,结束行,起始列,结束列
CellRangeAddress callRangeAddress39 = new CellRangeAddress(15, 16, 0, 7);// 起始行,结束行,起始列,结束列
CellRangeAddress callRangeAddress40 = new CellRangeAddress(17, 18, 0, 7);// 起始行,结束行,起始列,结束列
CellRangeAddress callRangeAddress41 = new CellRangeAddress(19, 20, 0, 7);// 起始行,结束行,起始列,结束列
CellRangeAddress callRangeAddress42 = new CellRangeAddress(21, 22, 0, 7);// 起始行,结束行,起始列,结束列
CellRangeAddress callRangeAddress43 = new CellRangeAddress(23, 24, 0, 7);// 起始行,结束行,起始列,结束列
CellRangeAddress callRangeAddress44 = new CellRangeAddress(25, 26, 0, 7);// 起始行,结束行,起始列,结束列
CellRangeAddress callRangeAddress45 = new CellRangeAddress(27, 34, 0, 7);// 起始行,结束行,起始列,结束列
CellRangeAddress callRangeAddress47 = new CellRangeAddress(35, 35, 0, 7);// 起始行,结束行,起始列,结束列
HSSFCellStyle erStyle = createCellStyle(workbook, (short) 13, true, true, false);
HSSFCellStyle sanStyle = createCellStyle(workbook, (short) 10, true, false, false);
HSSFCellStyle nameStyle = createCellStyle(workbook, (short) 10, false, false, false);
HSSFCellStyle dataStyle = createCellStyle(workbook, (short) 10, false, true, false);
// 创建工作表
HSSFSheet sheet = workbook.createSheet();
// 加载合并单元格对象
sheet.addMergedRegion(callRangeAddress);
sheet.addMergedRegion(callRangeAddress1);
sheet.addMergedRegion(callRangeAddress20);
sheet.addMergedRegion(callRangeAddress21);
sheet.addMergedRegion(callRangeAddress22);
sheet.addMergedRegion(callRangeAddress31);
sheet.addMergedRegion(callRangeAddress32);
sheet.addMergedRegion(callRangeAddress34);
sheet.addMergedRegion(callRangeAddress35);
sheet.addMergedRegion(callRangeAddress36);
sheet.addMergedRegion(callRangeAddress37);
sheet.addMergedRegion(callRangeAddress38);
sheet.addMergedRegion(callRangeAddress39);
sheet.addMergedRegion(callRangeAddress40);
sheet.addMergedRegion(callRangeAddress41);
sheet.addMergedRegion(callRangeAddress42);
sheet.addMergedRegion(callRangeAddress43);
sheet.addMergedRegion(callRangeAddress44);
sheet.addMergedRegion(callRangeAddress45);
sheet.addMergedRegion(callRangeAddress47);
// 设置默认列宽
sheet.setDefaultColumnWidth(15);
// 标题
HSSFRow rower = sheet.createRow(0);
HSSFCell celler = rower.createCell(0);
celler.setCellStyle(erStyle);
celler.setCellValue("融资租赁收费确认单");
// 客户姓名,手机号码
HSSFRow rowsan = sheet.createRow(3);
HSSFCell cellsan = rowsan.createCell(0);
HSSFCell cellsan2 = rowsan.createCell(3);
cellsan.setCellStyle(sanStyle);
cellsan.setCellValue("客户姓名: " + jrUser.getRealName());
cellsan2.setCellStyle(sanStyle);
cellsan2.setCellValue("手机号码: " + jrUser.getTelphone());
// 车型
HSSFRow rowCar = sheet.createRow(5);
HSSFCell carsan = rowCar.createCell(0);
carsan.setCellStyle(sanStyle);
if ("0".equals(jrUserOrders.getCarType())) {
carsan.setCellValue("车型: " + "新车");
} else if ("1".equals(jrUserOrders.getCarType())) {
carsan.setCellValue("车型: " + "二手车");
} else {
carsan.setCellValue("车型: " + "");
}
// 车价,购置税,保险
HSSFRow rowpersion = sheet.createRow(7);
HSSFCell cellpersion = rowpersion.createCell(0);
HSSFCell cellpersion1 = rowpersion.createCell(3);
HSSFCell cellpersion2 = rowpersion.createCell(5);
cellpersion.setCellStyle(sanStyle);
cellpersion.setCellValue("车价: " + jrUserOrders.getCarPrice() + " 元");
cellpersion1.setCellStyle(sanStyle);
cellpersion1.setCellValue("购置税: " + jrUserOrders.getPurchaseTax() + " 元");
cellpersion2.setCellStyle(sanStyle);
cellpersion2.setCellValue("保险: " + jrUserOrders.getInsurance() + " 元");
// 首付贷
HSSFRow rowOne = sheet.createRow(9);
HSSFCell onesan = rowOne.createCell(0);
onesan.setCellStyle(sanStyle);
onesan.setCellValue("首付贷: " + jrUserOrders.getDownPayments() + " 元");
// 车价,购置税,保险
HSSFRow rowRz = sheet.createRow(11);
HSSFCell cellrz = rowRz.createCell(0);
HSSFCell cellqs = rowRz.createCell(3);
HSSFCell cellmonth = rowRz.createCell(5);
cellrz.setCellStyle(sanStyle);
cellrz.setCellValue("融资金额: " + jrUserOrders.getRzAmt() + " 元");
cellqs.setCellStyle(sanStyle);
cellqs.setCellValue("期数: " + jrUserOrders.getRzqs() + " 期");
cellmonth.setCellStyle(sanStyle);
cellmonth.setCellValue("月还款额: " + jrUserOrders.getMonthPay() + " 元");
// 保证金
HSSFRow rowamt = sheet.createRow(13);
HSSFCell amtsan = rowamt.createCell(0);
amtsan.setCellStyle(sanStyle);
amtsan.setCellValue("保证金: " + jrUserOrders.getBond() + " 元" + " (总额5%)");
// 手续费
HSSFRow proceduresrow = sheet.createRow(15);
HSSFCell proceduresAmt = proceduresrow.createCell(0);
proceduresAmt.setCellStyle(sanStyle);
proceduresAmt.setCellValue("手续费: " + jrUserOrders.getProceduresAmt() + " 元" + " (总额3%)");
// 续保押金
HSSFRow renewDepositrow = sheet.createRow(17);
HSSFCell renewDeposit = renewDepositrow.createCell(0);
renewDeposit.setCellStyle(sanStyle);
renewDeposit.setCellValue("续保押金: " + jrUserOrders.getRenewDeposit() + " 元");
// GPS费
HSSFRow gps = sheet.createRow(19);
HSSFCell gpssan = gps.createCell(0);
gpssan.setCellStyle(sanStyle);
gpssan.setCellValue("GPS费: " + jrUserOrders.getGpsAmt() + " 元");
// 公证费
HSSFRow notarization = sheet.createRow(21);
HSSFCell notarizationAmt = notarization.createCell(0);
notarizationAmt.setCellStyle(sanStyle);
notarizationAmt.setCellValue("公证费: " + jrUserOrders.getNotarizationAmt() + " 元");
// 家访费
HSSFRow home = sheet.createRow(23);
HSSFCell homesan = home.createCell(0);
homesan.setCellStyle(sanStyle);
homesan.setCellValue("家访费: " + jrUserOrders.getHomeVisitAmt() + " 元");
// 其他
HSSFRow other = sheet.createRow(25);
HSSFCell othersan = other.createCell(0);
othersan.setCellStyle(sanStyle);
othersan.setCellValue("其他: " + jrUserOrders.getHomeVisitAmt() + " 元");
// 签名
HSSFRow png = sheet.createRow(27);
HSSFCell pngsan = png.createCell(0);
pngsan.setCellStyle(nameStyle);
pngsan.setCellValue("以上收费标准本人已确认无误.客户签名: ");
HSSFPatriarch patriarch = sheet.createDrawingPatriarch();
drawPictureInfoExcel(workbook, patriarch, imageUrl);
// 签名日期
HSSFRow pngDate = sheet.createRow(35);
HSSFCell pngDatesan = pngDate.createCell(0);
pngDatesan.setCellStyle(dataStyle);
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
pngDatesan.setCellValue("日期: " + simpleDateFormat.format(jrUserOrders.getCreatedate()));
// 5.输出
workbook.write(outData);
// workbook.close();
// out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/** 单元格样式*/
private static HSSFCellStyle createCellStyle(HSSFWorkbook workbook, short fontsize, boolean flagRow, boolean flagC,boolean flagDate) {
// TODO Auto-generated method stub
HSSFCellStyle style = workbook.createCellStyle();
// 是否水平居中
if (flagRow) {
style.setVerticalAlignment(VerticalAlignment.CENTER);// 水平居中
} else {
style.setVerticalAlignment(VerticalAlignment.TOP);
}
// 创建字体
HSSFFont font = workbook.createFont();
// 是否加粗字体
if (flagC) {
style.setAlignment(HorizontalAlignment.CENTER);// 垂直居中
font.setFontHeightInPoints((short) 10);
}
if (flagDate) {
style.setAlignment(HorizontalAlignment.RIGHT);// 垂直居右
font.setFontHeightInPoints((short) 8);
}
font.setFontHeightInPoints(fontsize);
// 加载字体
style.setFont(font);
return style;
}
public static void drawPictureInfoExcel(HSSFWorkbook wb, HSSFPatriarch patriarch, String imageUrl) {
try {
URL url = new URL(imageUrl);
// 打开链接
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
// 设置请求方式为"GET"
conn.setRequestMethod("GET");
// 超时响应时间为5秒
conn.setConnectTimeout(5 * 1000);
// 通过输入流获取图片数据
InputStream inStream = conn.getInputStream();
byte[] data = readInputStream(inStream);
// anchor主要用于设置图片的属性
// HSSFClientAnchor hssfClientAnchor = new
// HSSFClientAnchor(dx1,dy1,dx2,dy2,col1,row1,col2,row2);
HSSFClientAnchor anchor = new HSSFClientAnchor(0, 0, 0, 0, (short) 0, 28, (short) 8, 35);
// 图片在单元格的位置
anchor.setAnchorType(AnchorType.DONT_MOVE_AND_RESIZE);
patriarch.createPicture(anchor, wb.addPicture(data, HSSFWorkbook.PICTURE_TYPE_JPEG));
} catch (Exception e) {
e.printStackTrace();
}
}
private static byte[] readInputStream(InputStream inStream) throws Exception {
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
// 创建一个Buffer字符串
byte[] buffer = new byte[1024];
// 每次读取的字符串长度,如果为-1,代表全部读取完毕
int len = 0;
// 使用一个输入流从buffer里把数据读取出来
while ((len = inStream.read(buffer)) != -1) {
// 用输出流往buffer里写入数据,中间参数代表从哪个位置开始读,len代表读取的长度
outStream.write(buffer, 0, len);
}
// 关闭输入流
inStream.close();
// 把outStream里的数据写入内存
return outStream.toByteArray();
}
/*
* public static void main(String args[]){ //模拟部分数据 try { FileOutputStream
* fout = new FileOutputStream("I:/333.xls"); // new
* ExportExcel().getValue(fout); fout.close(); } catch (Exception e) {
* e.printStackTrace(); }
*
* }*/
}
其中单元格样式网上大部分的POI 都是老版本的,所以有许多代码没有相关的api, 上面的代码中单元格样式相关API是新版的,代码都可以直接使用。
2. 样式什么的都创建好了,接下来就是使用调用了(controller),
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
String date = simpleDateFormat.format(new Date()).toString();
String fileName = date + jrUser.getRealName() + "/融资租赁收费确认单";
OutputStream outData = response.getOutputStream();
response.reset();
response.setContentType("application/vnd.ms-excel;charset=gbk");
response.addHeader("Content-Disposition",
"attachment;filename=" + new String((fileName + ".xls").getBytes("gbk"), "ISO-8859-1"));
ExportExcel exportExcel = new ExportExcel();
String basePath = request.getContextPath();
String imagePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()
+ basePath + "/ui/rzJs/orders.png";
exportExcel.getValue(jrUser, jrUserOrders, imagePath, outData);
3. jsp当然少不了,当然了,如果你不是做成弹窗式下载,就可以不要弹窗jsp,把2中的代码改成用流写入到本地位置即可
<form id="myform" enctype="multipart/form-data" action="<%=basePath%>/rzJrUsre/batchExport" method="post" role="form">
<table>
<tr>
<td><input type="submit" value="导出" style="margin-left: 1550px;" /></td>
</tr>
</table>
</form>
以上代码都是可以直接使用的,当然了如果有什么不能使用的地方,就需要各位大神自己动手改改相关代码了,毕竟环境,需求不可能一定相同。其实POI使用原理也挺简单的,就是弄个模板,然后用流将信息写入,用流操作。明白这些使用POI也不难。
最后是Echarts,是百度的一款做报表的相关开源API,http://www.echartsjs.com/index.html 这是首页链接,使用相对于来说跟table2一样也挺简单,引入js,使用api。 当然了也有其局限性:数据量一大就不行了,不过其美观性方面确实不错。 这有一个基于Echarts开发的软件:http://www.smartbi.com.cn/spreadsheet 其做的相对很好。其中大量案例,模板,可以进去看看,再根据Echarts官方的API,文档就很容易理解,上手Echarts了。
Echarts导出有图片时,传到后台的是base64编码的字符串,所以后台接收需要做出相关处理。
function getFullCanvasDataURL(divId){
//将第一个画布作为基准。
var baseCanvas = $("#"+divId).find("canvas").first()[0];
if(!baseCanvas){
return false;
};
var width = baseCanvas.width;
var height = baseCanvas.height;
var ctx = baseCanvas.getContext("2d");
//遍历,将后续的画布添加到在第一个上
$("#"+divId).find("canvas").each(function(i,canvasObj){
if(i>0){
var canvasTmp = $(canvasObj)[0];
ctx.drawImage(canvasTmp,0,0,width,height);
}
});
//获取base64位的url
return baseCanvas.toDataURL();
}
function importBtnn() {
var data = getFullCanvasDataURL("main");
$("#img").val(data);
var img= $("#img").val();
$("#myform").submit();
};
我想有了这三种制作表格的方式足以实现业务中的需求了。有不懂的, 有问题,有建议欢迎大家随时提出,自己也是刚开始写博客。希望能坚持,努力下去,学无止境。
在此,希望此篇博客能帮助到一些人。有不足之处,有问题的话可以博客上Q我,看到就会回复
报表生成(POI,jquery.table2excel.js,Echarts)的更多相关文章
- jquery插件导出word:jquery.wordexport.js
前言 今天项目中遇到一个需求把我们系统中的统计数据导出来(主要是表格).其实实现的的方法有很多,而此次针对我的系统第一获取数据有点慢,加上前不久写了一个在线阅读pdf,故此这次也想用前端的方式来导出. ...
- jquery.table2excel,将HTML的table标签数据导出成excel
<!DOCTYPE> <html> <head> <meta http-equiv="Content-Type" content=&quo ...
- jquery.wordexport.js打印echarts.js画出的柱状图
jquery.wordexport.js打印echarts.js画出的柱状图. echarts画出的图是不能直接打印出来的(echarts的柱状图是用canvas画出来的),而jquery.worde ...
- jquery.js和jquery.min.js的区别和springboot整合echarts.min.js
1.区别:jquery官网提供2种jQuery的下载,一种是jquery.js另一种是jquery.min.js文件名不一定完全相同,但通常情况下:jquery.js是完整的未压缩的jQuery库,文 ...
- Spring Data Jpa+SpringMVC+Jquery.pagination.js实现分页
本博客介绍基于Spring Data这款orm框架加上Jquery.pagination插件实现的分页功能. 介绍一下Spring Data框架 spring Data : Spring 的一个子项目 ...
- a页面通过url传值,b页面如何接收(jquery.params.js实现)
用于两个html页面之间的传值 我的应用场景是:用echarts在a页面做完中国地图后,点击某个省份在b页面显示某个省份的地图.(在b页面显示点击了的那个省份的地图,等于说b页面是个“容器”页) 假设 ...
- SaaS系统怎么做物流行业年度经营报告,MVC+js+echarts实现
前言 马上就到年底了,很多公司都要汇总这一年的经营情况,如果一个系统没有自动生成年报的功能, 需要人工手工去做年报,我相信可能是一个不小的工作量,最近我通过一个星期的时间,结合系统情况自动生成年报,全 ...
- jquery和Js的区别和基础操作
jqery的语法和js的语法一样,算是把js升级了一下,这两种语法可以一起使用,只不过是用jqery更加方便 一个页面想要使用jqery的话,先要引入一下jqery包,jqery包从网上下一个就可以, ...
- jQuery.template.js 简单使用
之前看了一篇文章<我们为什么要尝试前后端分离>,深有同感,并有了下面的评论: 我最近也和前端同事在讨论这个问题,比如有时候前端写好页面给后端了,然后后端把这些页面拆分成很多的 views, ...
随机推荐
- asp.net core 3.x 身份验证-3cookie身份验证原理
概述 上两篇(asp.net core 3.x 身份验证-1涉及到的概念.asp.net core 3.x 身份验证-2启动阶段的配置)介绍了身份验证相关概念以及启动阶段的配置,本篇以cookie身份 ...
- ncbi-blast 本地安装
详见:http://blog.shenwei.me/local-blast-installation/ Linux系统中NCBI BLAST+本地化教程 本文面向初学者(最好还是懂得基本的linux使 ...
- Mysql事务结合spring管理
spring事务相关问题记录 遇到情况: 在本地单体应用调试代码时,发现在一个加了@transaction注解的方法里进行先更新后查询的操作,查询的结果是可以看到更新的内容的.而在微服务环境中同样的代 ...
- Go语言实现:【剑指offer】对称的二叉树
该题目来源于牛客网<剑指offer>专题. 请实现一个函数,用来判断一颗二叉树是不是对称的.注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的. Go语言实现: 方法一:递归 / ...
- 小白的springboot之路(十五)、mybatis的PageHelper分页插件使用
0.前言 用mybatis,那么分页必不可少,基本都是用PageHelper这个分页插件,好用方便: 1.实现 1.1.添加依赖: <!-- 3.集成 mybatis pagehelper--& ...
- k8s系列---stateful(有状态应用副本集)控制器
http://blog.itpub.net/28916011/viewspace-2215046/ 在应用程序中,可以分为有状态应用和无状态应用. 无状态的应用更关注于群体,任何一个成员都可以被取代. ...
- Django (一) 基础
创建项目 创建app python manager.py startapp app01 修改.添加url from django.conf.urls import url,include fr ...
- php插件名称 yum安装
提示缺少 安装 DOM扩展模块 yum install php-xml PDO ...
- Keras入门(六)模型训练实时可视化
在北京做某个项目的时候,客户要求能够对数据进行训练.预测,同时能导出模型,还有在页面上显示训练的进度.前面的几个要求都不难实现,但在页面上显示训练进度当时笔者并没有实现. 本文将会分享如何在K ...
- 多线程共享变量和 AsyncLocal
>>返回<C# 并发编程> 1. 简介 2. 异步下的共享变量 3. 解析 AsyncLocal 3.1. IAsyncLocalValueMap 的实现 3.2. 结论 1. ...