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. 这才是图文并茂:我写了1万多字,就是为了让你了解AQS是怎么运行的

    前言 如果你想深入研究Java并发的话,那么AQS一定是绕不开的一块知识点,Java并发包很多的同步工具类底层都是基于AQS来实现的,比如我们工作中经常用的Lock工具ReentrantLock.栅栏 ...

  2. Python_爬虫伪装_ scrapy中fake_userAgent的使用

    scrapy 伪装代理和fake_userAgent的使用 伪装浏览器代理 在爬取网页是有些服务器对请求过滤的不是很高可以不用ip来伪装请求直接将自己的浏览器信息给伪装也是可以的. 第一种方法: 1. ...

  3. 精尽 MyBatis 源码分析 - 整体架构

    该系列文档是本人在学习 Mybatis 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释(Mybatis源码分析 GitHub 地址.Mybatis-Spring 源码分析 GitHub ...

  4. Spring MVC——项目的开发流程

    创建项目(IDEA下) 打开IDEA,我们开始创建一个简单的Spring MVC项目,流程如下: 这里要注意一下,我们是基于Maven开发项目,当然是要配置Maven环境的,如果大家之前从来没有配置过 ...

  5. jwt鉴权学习 (php示例代码)

    前段时间听朋友讲起 jwt鉴权,博主我是一脸懵逼,通过朋友坚持不懈的讲解,我终于听懂了,jwt就是登陆token校验嘛 然而事情并不是博主想象的那么简单,在一个艳阳高照,晴空万里的夜晚,博主手贱百度了 ...

  6. Python:利用Entrez库筛选下载PubMed文献摘要

    一个不是学生物的孩子来搞生物,当真是变成了一块废铁啊,但也是让我体会到了一把生物信息的力量. 废话不多说,开整! 任务:快速高效从PubMed上下载满足条件的文献PMID.标题(TI).摘要(AB). ...

  7. 历时两年零三个月,从刚毕业的外包到现在的阿里P7offer,我只做了这几件事

    前言 最近,金九银十在即,很多人都在准备面试,特别给大家总结了 Java 程序员面试必备题,这份面试清单是我从 去年开始收集的,一方面是给公司招聘用,另一方面是想用它来挖掘我在 Java 技术栈中的技 ...

  8. 思维导图软件iMindMap制作技巧有哪些

    iMindMap11是iMindMap全新的版本.它可以提供给我们更好的灵活性以便我们将我们的思维进行可视化,并进一步的呈现和开发出属于自己的想法以及思维方式.在iMindMap中我们可以利用思维导图 ...

  9. Guitar Pro 7教程之添加音轨讲解

    Guitar Pro 7是当前的新版本,较之前版本GP5,GP6,不管在功能还是软件的界面上都是有了不一样的改变,最近听到很多朋友说,由于Guitar Pro 7界面与之前完全不一样,很多功能都不知道 ...

  10. IDM下载器的队列功能有什么用?

    使用IDM下载器中的队列功能,可以帮助大家快速分类下载任务,这样,就可以统一管理有同样下载需求的内容. 一.队列的添加及设置 打开IDM下载器,单击菜单中的"队列",可以看到在左侧 ...