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. shell简介及变量的定义查看撤销

    1.shell分类及相关软件  图形界面Shell(Graphical User Interface shell 即 GUI shell),如:GNOME.KDE 命令行式Shell(Command ...

  2. Adaboost算法的一个简单实现——基于《统计学习方法(李航)》第八章

    最近阅读了李航的<统计学习方法(第二版)>,对AdaBoost算法进行了学习. 在第八章的8.1.3小节中,举了一个具体的算法计算实例.美中不足的是书上只给出了数值解,这里用代码将它实现一 ...

  3. Spring源码理论

    Spring Bean的创建过程: Spring容器获取Bean和创建Bean都会调用getBean()方法. getBean()方法 1)getBean()方法内部最终调用doGetBean()方法 ...

  4. Spark3.0.1各种集群模式搭建

    对于spark前来围观的小伙伴应该都有所了解,也是现在比较流行的计算框架,基本上是有点规模的公司标配,所以如果有时间也可以补一下短板. 简单来说Spark作为准实时大数据计算引擎,Spark的运行需要 ...

  5. API的使用(3)Arrays 类,Math类,三大特性--继承

    Arrays类 概述   java.util.Arrays此时主要是用来操作数组,里面提供了很多的操作API的方法.如[排序]和[搜索]功能.其所有的方法均为静态方法,调用起来非常简单. 操作数组的方 ...

  6. 什么是NTFS文件格式

    说到磁盘格式,想必大家对于NTFS格式并不陌生.我们使用的u盘等硬盘设备很多都应用了此格式.NTFS文件格式究竟是什么?它都有哪些特点?今天,小编将利用这篇文章为大家进行介绍. 一.什么是NTFS文件 ...

  7. bash反弹shell检测

    1.进程 file descriptor 异常检测 检测 file descriptor 是否指向一个socket 以重定向+/dev/tcp Bash反弹Shell攻击方式为例,这类反弹shell的 ...

  8. Pytest学习(十一)- 失败重跑插件pytest-rerunfailures的使用

    环境依赖 Python 3.5, 最高 3.8, or PyPy3 pytest 5.0或更高版本 插件安装 pip3 install pytest-rerunfailures -i http://p ...

  9. Centos7安装Nginx详细步骤

    前言 Nginx 是一款轻量级的Web 服务器 .反向代理服务器及电子邮件(IMAP/POP3)代理服务器. 常用用途: ✓ 1. 反向代理 ✓ 2. 正向代理 这里我给来2张图,对正向代理与反响代理 ...

  10. Java基础教程——Jshell

    Jshell 从java9开始,java提供Jshell工具,可以输入代码片段并马上看到运行结果. 对于简单的Java语句测试,不需要新建文件,编译,运行了 Microsoft Windows [版本 ...