Controller

Map<String,List<PoiUtilHeader>> result = new HashMap<String, List<PoiUtilHeader>>();
List<PoiUtilHeader> row0 = new ArrayList<PoiUtilHeader>();
row0.add(new PoiUtilHeader(0,"id",1,false));
row0.add(new PoiUtilHeader(0,"name",1,false));
row0.add(new PoiUtilHeader(0,"age",1,false));
row0.add(new PoiUtilHeader(0,"statue",1,false));
List<Record> invList =Db.find("select * from user");
String uuid=UuidUtil.get16UUId()+"RZJGDC.xls";
String[] fields=new String[]{"id","name","age","statue"};
render(PoiUtilRender.data(invList).headers(result).fileName(uuid).fields(fields));

PoiUtilHeader

package com.tax.common.util;

public class PoiUtilHeader{

    //表头等级
private int level=0;
//表头名称
private String columnsName="";
//所占列数
private int cellCount=0;
//是否有子节点
private boolean isChildren=false; public PoiUtilHeader(int level,String columnsName,int cellCount,boolean isChildren){
this.level=level;
this.columnsName=columnsName;
this.cellCount=cellCount;
this.isChildren=isChildren;
}
public PoiUtilHeader(int level,String columnsName,int cellCount){
this.level=level;
this.columnsName=columnsName;
this.cellCount=cellCount;
}
public PoiUtilHeader(int level,String columnsName,boolean isChildren){
this.level=level;
this.columnsName=columnsName;
this.isChildren=isChildren;
}
public PoiUtilHeader(int level,String columnsName){
this.level=level;
this.columnsName=columnsName;
}
public int getLevel() {
return level;
}
public void setLevel(int level) {
this.level = level;
}
public String getColumnsName() {
return columnsName;
}
public void setColumnsName(String columnsName) {
this.columnsName = columnsName;
}
public int getCellCount() {
return cellCount;
}
public void setCellCount(int cellCount) {
this.cellCount = cellCount;
}
public boolean getIsChildren() {
return isChildren;
}
public void setIsChildren(boolean isChildren) {
this.isChildren = isChildren;
} }

service  数据处理

     List listexcel = new ArrayList();
if(!invlist.isEmpty()){
for (int i = 0; i < invlist.size(); i++) {
Record mapDc = new Record();
Record record = (Record) invlist.get(i);
String statuea="";
if (record.get("statue").equals("0")) {
statuea="正常";
}else{
statuea="作废";
} mapDc.set("invtype", invtypea);
mapDc.set("period", record.get("id", ""));
mapDc.set("create_time", record.get("name", ""));
mapDc.set("create_time", record.get("age", ""));
listexcel.add(mapDc);
}
} return listexcel;

PoiUtilRender

package com.tax.common.util;

import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set; import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddress;
import com.jfinal.plugin.activerecord.Model;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.render.Render;
import com.jfinal.render.RenderException; /**
* 导出2003的excel表格,超过65535行可能会报错
* 多行跨行跨列表头算法
* @author by:zy
*/
@SuppressWarnings("unchecked")
public class PoiUtilRender extends Render { public final static String H_MAP_NAME="tName";
public final static String H_MAP_SUBNAME="tSubName"; private final String CONTENT_TYPE = "application/msexcel;charset=" + getEncoding();
/*private final String VERSION_2003 = "2003";
private final int MAX_ROWS = 65535;*/
private String fileName = "file1.xls";
private String sheetName = "sheet";
private Map<String,List<PoiUtilHeader>> headers = new HashMap<String,List<PoiUtilHeader>>();
private String[] fields =null;
private List<?> data =null; public PoiUtilRender(List<?> data){
this.data=data;
}
@Override
public void render() {
response.reset();
response.setHeader("Content-disposition", "attachment; filename=" + fileName);
response.setContentType(CONTENT_TYPE);
OutputStream os = null;
try {
os = response.getOutputStream();
export().write(os);
} catch (Exception e) {
throw new RenderException(e);
} finally {
try {
if (os != null) {
os.flush();
os.close();
}
} catch (IOException e) {
//LOG.error(e.getMessage(), e);
} }
} /**
* 核心方法
*/
public Workbook export() {
HSSFWorkbook wb = new HSSFWorkbook();
HSSFSheet sheet = wb.createSheet(sheetName);
sheet.setDefaultColumnWidth(12);
Row row;
Cell cell;
//表头
int headerRow =0;
if (this.headers != null && !this.headers.isEmpty()) { headerRow = headers.size();
HSSFCellStyle headerStyle = this.getColumnTopStyle(wb);//获取列头样式
Set<String> occupyCell =new HashSet<String>(); //总行数
int maxCellCount=0;
for (PoiUtilHeader p : headers.get("row0")) {
maxCellCount+=p.getCellCount();
} for (int i = 0, len = headers.size(); i < len; i++) {
List<PoiUtilHeader> list = headers.get("row" + i);
row = sheet.createRow(i);
row.setHeightInPoints(30);//设置高度 int index = 0;
int lastIndex = list.size();
for (int j = 0, jlen = maxCellCount; j < jlen; j++) {
//超出索引退出
if(index>=lastIndex){break;}
//是否已被占用
if(occupyCell.contains(i+"-"+j)){continue;} PoiUtilHeader h = list.get(index);
//计算跨行的起点
int lastRowNum=i;
//计算跨行跨列
int lastCellNum = j + h.getCellCount()-1; if(!h.getIsChildren()){lastRowNum=len-1;}
cell = row.createCell(j);
cell.setCellValue(h.getColumnsName());
cell.setCellStyle(headerStyle); for(int r = i ; r<=lastRowNum ; r++){
for(int c = j ; c<=lastCellNum ; c++){
occupyCell.add(r+"-"+c);
}
}
sheet.addMergedRegion(new CellRangeAddress(i, lastRowNum, j, lastCellNum));
index++;
}
}
}
//sheet.setColumnWidth(j, h.getColumnsName().getBytes().length*2*1000); //内容
if(data!=null){
for (int i = 0, len = data.size(); i < len; i++) {
row = sheet.createRow(i + headerRow);
row.setHeightInPoints(20);//设置高度
Object obj = data.get(i);
if (obj == null) {
continue;
}
if (obj instanceof Map) {
processAsMap(row, obj);
} else if (obj instanceof Model) {
processAsModel(row, obj);
} else if (obj instanceof Record) {
processAsRecord(row, obj);
} else if(obj instanceof List){
processAsList(row,obj);
}else{
throw new RuntimeException("Not support type[" + obj.getClass() + "]");
}
}
}
return wb;
} /*
* 列头单元格样式
*/
public HSSFCellStyle getColumnTopStyle(HSSFWorkbook workbook) {
// 设置字体
HSSFFont font = workbook.createFont();
//设置字体大小
font.setFontHeightInPoints((short)10);
//字体加粗
//font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
//设置字体名字
font.setFontName("Microsoft YaHei");
//设置样式;
HSSFCellStyle style = workbook.createCellStyle();
//在样式用应用设置的字体;
style.setFont(font);
//设置自动换行;
style.setWrapText(true);
//设置水平对齐的样式为居中对齐;
style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
//设置垂直对齐的样式为居中对齐;
style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
//设置背景颜色;
style.setFillForegroundColor(new HSSFColor.BLUE_GREY().getIndex()); return style; } private void processAsMap(Row row, Object obj) {
Cell cell;
Map<String, Object> map = (Map<String, Object>) obj;
if(fields!=null && fields.length>0){
for(int columnIndex = 0 , len = fields.length ; columnIndex<len ; columnIndex++){
String key = fields[columnIndex];
cell = row.createCell(columnIndex);
cell.setCellValue(map.get(key) == null ? "" : map.get(key) + "");
}
}else{
int columnIndex = 0;
for(String key : map.keySet()){
cell = row.createCell(columnIndex);
cell.setCellValue(map.get(key) == null ? "" : map.get(key) + "");
columnIndex++;
}
}
}
private void processAsModel(Row row, Object obj) {
Cell cell;
Model<?> model = (Model<?>) obj;
if(fields!=null && fields.length>0){
for(int columnIndex = 0 , len = fields.length ; columnIndex<len ; columnIndex++){
String key = fields[columnIndex];
cell = row.createCell(columnIndex);
cell.setCellValue(model.get(key) == null ? "" : model.get(key) + "");
}
}else{
int columnIndex = 0;
Object[] vals = model._getAttrValues();
for(Object v : vals){
cell = row.createCell(columnIndex);
cell.setCellValue(v == null ? "" : v + "");
columnIndex++;
}
}
} private void processAsList(Row row, Object obj) {
Cell cell;
System.out.println("scb");
List record = (List) obj;
if(fields!=null && fields.length>0){
for(int columnIndex = 0 , len = fields.length ; columnIndex<len ; columnIndex++){
String key = fields[columnIndex];
cell = row.createCell(columnIndex);
cell.setCellValue(record.get(0) == null ? "" : record.get(0) + "");
}
}else{
int columnIndex = 0;
Record red=new Record();
Object[] vals = red.getColumnValues();
for(Object v : vals){
cell = row.createCell(columnIndex);
cell.setCellValue(v == null ? "" : v + "");
columnIndex++;
}
}
} private void processAsRecord(Row row, Object obj) {
Cell cell;
Record record = (Record) obj;
if(fields!=null && fields.length>0){
for(int columnIndex = 0 , len = fields.length ; columnIndex<len ; columnIndex++){
String key = fields[columnIndex];
cell = row.createCell(columnIndex);
cell.setCellValue(record.get(key) == null ? "" : record.get(key) + "");
}
}else{
int columnIndex = 0;
Object[] vals = record.getColumnValues();
for(Object v : vals){
cell = row.createCell(columnIndex);
cell.setCellValue(v == null ? "" : v + "");
columnIndex++;
}
}
} private int setHeader(int level , List<Map<String, Object>> titles){
if(titles==null || titles.isEmpty()) return 1;
int resultNum=0;
List<PoiUtilHeader> h = (this.headers.get("row"+level)==null?new ArrayList<PoiUtilHeader>():this.headers.get("row"+level));
for(Map<String,Object> t : titles){
int subNum = 0;
boolean isChildren=false;
if(t.get(H_MAP_SUBNAME) instanceof List){
isChildren=true;
List<Map<String,Object>> subList = (List<Map<String,Object>>)t.get(H_MAP_SUBNAME) ;
subNum += setHeader(level+1, subList);
}
subNum = (subNum>0?subNum:1);
resultNum+=subNum;
h.add(new PoiUtilHeader(level, t.get(H_MAP_NAME)+"",subNum,isChildren));
}
this.headers.put("row"+level,h); if(resultNum>titles.size()){
return resultNum;
}else{
return titles.size();
}
} public static PoiUtilRender data(List<?> data) {
return new PoiUtilRender(data);
}
/***
* 复杂的复合表头
* tName : 表头名称
* tSubName : 下级表头 List 数据
*
* 常量:
* public final String H_MAP_NAME="tName";
* public final String H_MAP_SUBNAME="tSubName";
*/
public PoiUtilRender headers(List<Map<String, Object>> titles) {
this.headers.clear();
if(titles!=null && !titles.isEmpty()){
List<PoiUtilHeader> h = new ArrayList<PoiUtilHeader>();
for(Map<String,Object> t : titles){
int subNum = 0;
boolean isChildren=false;
if(t.get(H_MAP_SUBNAME) instanceof List){
isChildren=true;
List<Map<String,Object>> subList = (List<Map<String,Object>>)t.get(H_MAP_SUBNAME) ;
subNum += setHeader(1, subList);
}
subNum = (subNum>0?subNum:1);
h.add(new PoiUtilHeader(0, t.get(H_MAP_NAME)+"",subNum,isChildren));
}
this.headers.put("row0",h);
}
return this;
} /**
* 设置普通单行表头
*/
public PoiUtilRender headers(String[] titles) {
this.headers.clear();
List<PoiUtilHeader> h = new ArrayList<PoiUtilHeader>();
for(String t :titles){
h.add(new PoiUtilHeader(0, t, 1, false));
}
this.headers.put("row0",h);
return this;
}
/**
* 设置复杂表头
*/
public PoiUtilRender headers(Map<String,List<PoiUtilHeader>> titles) {
this.headers.clear();
this.headers=titles;
return this;
}
/**
* 设置文件名称
*/
public PoiUtilRender fileName(String fileName) {
this.fileName = fileName;
return this;
}
/**
* 设置sheet名称
*/
public PoiUtilRender sheetName(String sheetName) {
this.sheetName = sheetName;
return this;
}
/**
* 设置数据字段名称,字段的顺序就是excel列的顺序,不设置就是按照存储集合的顺序排列
*/
public PoiUtilRender fields(String[] fields) {
this.fields = fields;
return this;
} }

jfinal 导出excle的更多相关文章

  1. 使导出excle文档实现ALT+Enter的效果()

    JAVA中输入什么转义字符,使导出excle文档实现ALT+Enter的效果?或者有没有其他方法可以实现. 20 JAVA中输入什么转义字符,使导出excle文档实现ALT+Enter的效果?或者有没 ...

  2. vue下载模板、导出excle

    1.下载模板是 下载模版比较简单,就是跳一个新的页面 2.导出excle 就是get请求,把自己要导出的参数一一拼接起来 }

  3. React+后端实现导出Excle表格的功能

    最近在做一个基于React+antd前端框架的Excel导出功能,我主要在后端做了处理,根据以下步骤,可以很容易就实现导出Excel表格数据的功能. 在做这类导出文件的功能,其实,在后端进行处理,会更 ...

  4. php 导出excle的.csv格式的数据时乱码问题

    1.header('Content-Encoding: XXXX'); 有可能是编码问题:可以尝试UTF-8,GBK,GB2312,等编码格式 2.有可能是文件编码问题,虽然UTF-8不建议带BOM, ...

  5. .net导出excle无需任何插件,直接通过一个tablehtml实现

    项目背景: 项目需要导出样式复杂的excl表格,主要是一些样式布局比较复杂 技术分析: 目前比较通用的实现方式有 1.借助微软的excle插件 2.通过NPOI插件实现 3.直接导出一个html(ta ...

  6. NPOI导出Excle

    前端: <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" con ...

  7. Poi导出Excle

    场景 准备金系统需要从数据库读取大量数据存放到List集合中(可能还会做逻辑上的处理),并生成一个Excle文件,下载到客户本地. 问题一:客户体验 如果导出的文件比较大,比如几十万条数据,同步导出页 ...

  8. sqlserver任务导出Excle

    --sql语句就用下面的存储过程 /*--数据导出Excel 导出查询中的数据到Excel,包含字段名,文件为真正的Excel文件,如果文件不存在,将自动创建文件,如果表不存在,将自动创建表基于通用性 ...

  9. asp.net导出excle

    思路:实际上是读取页面上某个控件下的内容再导出 protected void btnExcel_Click(object sender, EventArgs e) { string bgType = ...

随机推荐

  1. JavaScript高级程序设计(第四版) -- 随笔 -- 数组(未完)

    数组方法 .every() 与 .some() 传给两个个方法的函数都接收3个参数:数组元素.元素索引和数组本身. .every() -- 对于每一项都需要返回true,它才会返回true 若中途有一 ...

  2. deepin 安装最新版node

    安装npm sudo apt install npm 安装node sudo npm install -g n 升级node到稳定版 sudo n stable 升级到最新版 sudo n lates ...

  3. [原题复现+审计][RoarCTF 2019]Easy Calc(http协议走私、php字符串解析漏洞)

    简介  原题复现:  考察知识点:http协议走私.php字符串解析漏洞  线上平台:https://buuoj.cn(北京联合大学公开的CTF平台) 榆林学院内可使用信安协会内部的CTF训练平台找到 ...

  4. web安全原理-文件包含漏洞

    前言 起来吃完早饭就开始刷攻防世界的题,一个简单的文件包含题我竟然都做不出来我服了  拿出买的书开始从头学习总结文件包含漏洞! 一.文件包含漏洞 文件包含漏洞 文件包含函数的参数没有经过过滤或者严格的 ...

  5. phpstorm换行符设置LF

    git执行命令行 git config --global core.autocrlf true

  6. linux qt 5.12.6 编译mysql驱动

    环境:ubuntu 18.4 x64.qt 5.12.6 问题:安装后是没有mysql的驱动的 解决过程: 各种搜索,先后安装了mysql mysql-client,mysql-server,和各种l ...

  7. 这份java多线程笔记,你真得好好看看,我还没见过总结的这么全面的

    1.线程,进程和多线程 1.程序:指指令和数据的有序集合,其本身没有任何意义,是一个静态的概念 2.进程:指执行程序的一次执行过程,是一个动态的概念.是系统资源分配的单位(注意:很多多线程是模拟出来的 ...

  8. CSUST 4019 听党指挥(思维+模拟)

    题目链接 题目大意 给你一个长度为n的序列(n为偶数),序列为[1,2,3,....n],操作m次,进行m次操作后输出这个序列 有三种操作 1:每次将最左边的元素移到最右边,重复x次 2:每次将最右边 ...

  9. 渗透入门rop

    原文链接:https://blog.csdn.net/guiguzi1110/article/details/77663430?locationNum=1&fps=1 基本ROP 随着NX保护 ...

  10. 使用paho的MQTT时遇到的重连导致订阅无法收到问题和解决

    最近在使用MQTT来实现消息的传输,网上demo很多,这里就不在重复介绍了,直接上代码,百度就能出现一大堆 下面是MQTT实现订阅的主要代码部分 MqttClient client = new Mqt ...