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. 分布式监控系统之Zabbix基础

    1.为什么要使用监控系统? 我们知道一个系统不管怎么讲它都会出故障,我们为了保证线上业务的最大化的可用性,通常我们要给关键业务做高可用:做高可用的目的是为了让故障发生时,能够有一个备用的解决方案,将故 ...

  2. NOIP前一些题目的理解

    ZYB和售货机(图论,环) 题目链接 个人感觉这道题与基环树没有任何关系,你会发现,每个点最多只有一个入度和出度,所以只能是链或环. 还有就是本题的突破点就在于正确建图,题目的限制保证每个点的入度不大 ...

  3. 删除osd的正确方式

    在ceph的集群当中关于节点的替换的问题,一直按照以前的方式进行的处理,处理的步骤如下: 停止osd进程 /etc/init.d/ceph stop osd.0 这一步是停止osd的进程,让其他的os ...

  4. HDU100题简要题解(2080~2089)

    //2089之前忘做了,周二C语言课上做,至于2086,写题解的时候突然发现之前的做法是错的,新的解法交上去CE,等周二再弄吧,其余题目暂时可以放心 HDU2080 夹角有多大II 题目链接 Prob ...

  5. 【VUE】2.渲染组件&重定向路由

    1.删除多余组件,使环境赶紧 1. 整理App.vue, 删除多余内容,在template 模板区域增加一个路由占位符 router-view:渲染路径匹配到的视图组件 <template> ...

  6. python+requests之接口测试

    最近学习接口测试,测试工具玩的差不多了,想用代码来尝试一下. 发现一个简单的库,requests 一:安装 pip install requests 二:使用 import requests url ...

  7. 用FL Studio制作反向人声音效(Vocal Chops)

    人声切片在各类电子音乐中都被广泛运用,在FL Studio20中我们也可以运用其自带的插件来制作属于我们自己的人声切片效果.在学完这篇文章后你就可以动手做出如Kygo.Martin Garrix等大牌 ...

  8. dubbo源码调试

    1.从github上clone下duboo的源码并checkout tag到2.6.5可以看到如下的结构: 其中all-dubbo的pom如下: 这里会将dubbo的其他项目在package的时候打到 ...

  9. Mybatis学习-初步认知与使用

    Mybatis是一款优秀的持久层框架.且支持定制化SQL,存储过程以及高级映射 Mybatis几乎免除了所有的JDBC代码以及设置参数和获取结果集的工作,它使用简单的XML或注解来配置原始类型.接口和 ...

  10. matlab中实现 IEEE754浮点数 与 一般十进制数之间 互相转换的方法

    ------------恢复内容开始------------ %2020/12/2 11:42:31clcformat long % IEEE754 to deca = '40800000'a = d ...