1实例
复制代码
HSSFWorkbook workbook = new HSSFWorkbook();
HSSFSheet sheet = workbook.createSheet("sheet");
final HSSFCellStyle setBorder = workbook.createCellStyle();
setBorder.setVerticalAlignment(VerticalAlignment.CENTER);
setBorder.setAlignment(HorizontalAlignment.LEFT);
sheet.autoSizeColumn(0);
setBorder.setWrapText(true);
// 1
ListToCombineExcel process=createListToCombineExcel(workbook, sheet, setBorder);
List<FileAndFolderVO> fileAndFolderVOS = FileAndFolderVO.createList(list);
// 2
process.createSheetContent(fileAndFolderVOS);
String fileName = URLEncoder.encode(DateUtils.parseDateToStr("yyyyMMddHHmm",new Date())+".xlsx", "utf-8");
OutputStream out = null;
try {
out = response.getOutputStream();
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
// 代表的是Excel文件类型
response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
workbook.write(out);
} catch (IOException e) {
} finally {
try {
if (out != null) {
out.flush();
out.close();
}
workbook.close();
} catch (IOException e) {
}
}
2 FileAndFolderVO类
复制代码
@Data
public class FileAndFolderVO implements Serializable {
private static final long serialVersionUID = 1L;
private String id;
private String name;
private FileAndFolderVO parentFileAndFolderVO;
private static FileAndFolderVO createOrg(String id,String pId,String name)
{
FileAndFolderVO org=new FileAndFolderVO();
org.setId(id);
org.setName(name);
if(!pId.equals("0")){
FileAndFolderVO parent=new FileAndFolderVO();
parent.setId(pId);
org.setParentFileAndFolderVO(parent);
}
return org;
}
public static List<FileAndFolderVO> createList(List<FileAndFolder> fileAndFolderS)
{
List<FileAndFolderVO> list=new ArrayList();
for (FileAndFolder fileAndFolder : fileAndFolderS) {
list.add(createOrg(fileAndFolder.getId(),fileAndFolder.getParentId(),fileAndFolder.getName()));
}
return list;
}
}
3 ListToCombineExcel
复制代码
import org.apache.poi.hssf.usermodel.HSSFCell;
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.util.CellRangeAddress;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 把list转化成excel
*
*/
public abstract class ListToCombineExcel extends ListToTree{
private Map<String,HSSFRow> rowCache=new HashMap<String, HSSFRow>();
private Map<String,HSSFCell> cellCache=new HashMap<String, HSSFCell>();
private HSSFWorkbook workbook;
private HSSFSheet sheet;
private List<Node> treeNodes=null;
public ListToCombineExcel(HSSFWorkbook workbook, HSSFSheet sheet)
{
this.workbook=workbook;
this.sheet=sheet;
}
/**
* 创建excel的node
*/
@Override
protected Node createNode(Object target) {
return new ExcelNode(target);
}
/**
* 创建sheet的內容
*/
public void createSheetContent(List<? extends Object> list)
{
this.initTreeNodes(list);
this.processTreeNodes(this.treeNodes);
}
private void processTreeNodes(List nodes)
{
for (int i = 0;nodes!=null&& i < nodes.size(); i++) {
ExcelNode node=(ExcelNode) nodes.get(i);
this.processTreeNode(node);
}
}
private void processTreeNode(ExcelNode node)
{
//设置单元格内容
this.setCellContent(workbook, sheet, this.getRow(node.getRowNumber()), this.getCell(node.getRowNumber(), node.getCellNumber()), node);
//合并单元格
this.combineByExcelNode(node);
this.processTreeNodes(node.getChilds());
}
/**
* 把要处理的数据转成tree狀
* @param list
*/
private void initTreeNodes(List<? extends Object> list)
{
this.treeNodes=this.process(list);
for (int i = 0;treeNodes!=null &&i < treeNodes.size(); i++) {
ExcelNode node=(ExcelNode) treeNodes.get(i);
node.init(this.treeNodes);
}
}
/**
* 得到row
* @param rowNumber
* @return
*/
protected HSSFRow getRow(int rowNumber)
{
HSSFRow row=this.rowCache.get(String.valueOf(rowNumber));
if(null==row)
{
row=this.sheet.createRow(rowNumber);
this.rowCache.put(String.valueOf(rowNumber), row);
}
return row;
}
/**
* 得到cell
* @param rowNumber
* @param cellNumber
* @return
*/
protected HSSFCell getCell(int rowNumber , int cellNumber )
{
String key=rowNumber+"_"+cellNumber;
HSSFCell cell=this.cellCache.get(key);
if(null==cell)
{
HSSFRow row=this.getRow(rowNumber);
cell=row.createCell(cellNumber);
this.cellCache.put(key, cell);
}
return cell;
}
/**
* 根据node合并单元格
* @param node
*/
protected void combineByExcelNode(ExcelNode node)
{
int rowFrom = node.getRowFrom();
int rowTo = node.getRowTo();
//增加判断
if ((rowFrom!=rowTo)){
CellRangeAddress addressEpisodeProject = new CellRangeAddress( node.getRowFrom(), node.getRowTo(), node.getCellFrom(),node.getCellTo());
sheet.addMergedRegion(addressEpisodeProject);
}
}
/**
* 设置单元格内容
* @param workbook
* @param sheet
* @param row
* @param cell
* @param node
*/
public abstract void setCellContent(HSSFWorkbook workbook, HSSFSheet sheet, HSSFRow row, HSSFCell cell, ExcelNode node);
}
4 ListToTree
复制代码
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public abstract class ListToTree {
public List<Node> process(List<? extends Object> list) {
List<Node> nodes = new ArrayList<Node>();
for (int i = 0; list != null && i < list.size(); i++) {
Node node = this.createNode(list.get(i));
this.process(nodes, node);
}
return nodes;
}
/**
* 开始处理每一页
*
* @param nodes
* @param currentNode
*/
private void process(List<Node> nodes, Node currentNode) {
currentNodeAddChild(currentNode, nodes);//
currentNodeAddToParentDelegate(currentNode, nodes);
}
/**
* 在nodes中找到自己的子节点加入
*
* @param currentNode
* @param nodes
*/
private void currentNodeAddChild(Node currentNode, List<Node> nodes) {
if (nodes.size() < 1) {
return;
}
Iterator<Node> iter = nodes.iterator();
while (iter.hasNext()) {
Node item = iter.next();
if (this.isParent(currentNode, item)) {
currentNode.addChild(item);
iter.remove();
}
}
}
/**
* 在nodes中找到自己的父亲节点加入 如果沒有加入就把自己加入到nodes
*
* @param currentNode
* @param nodes
*/
private void currentNodeAddToParentDelegate(Node currentNode, List<Node> nodes)
{
if(!currentNodeAddToParent(currentNode, nodes))//如果沒有找到父亲节点自己加入nodes
{
nodes.add(currentNode);
}
}
/**
* 在nodes中找到自己的父亲节点加入
*
* @param currentNode
* @param nodes
*/
private boolean currentNodeAddToParent(Node currentNode, List<Node> nodes) {
for (int i = 0; nodes != null && i < nodes.size(); i++) {
Node parentNode=nodes.get(i);
if(this.isParent(parentNode, currentNode))
{
parentNode.addChild(currentNode);
return true;
}else
{
if(currentNodeAddToParent(currentNode, parentNode.getChilds()))
{
//成功加入
return true;
}
}
}
return false;
}
protected Node createNode(Object target) {
return new Node(target);
}
/**
* childNode 是不是parentNode的子节点
*
* @param parentNode
* @param childNode
* @return
*/
protected boolean isParent(Node parentNode, Node childNode) {
String id = this.getId(parentNode.getTarget());
return id != null && id.trim().length() > 0 && id.equals(this.getParentId(childNode.getTarget()));
}
/**
* 得到id
*
* @param obj
* @return
*/
protected abstract String getId(Object obj);
/**
* 得到父亲id
*
* @param obj
* @return
*/
protected abstract String getParentId(Object obj);
}
5 node
复制代码
import java.util.ArrayList;
import java.util.List;
/**
*
*
*/
public class Node {
protected Object targetObj;
protected int level;// 层级
protected int countLeaf;// 所以叶子个数
protected Node parentNode;
protected List<Node> childs = new ArrayList<Node>();
public Node()
{
this(null);
}
public Node(Object target)
{
this.targetObj=target;
}
public void addChild(Node node) {
this.childs.add(node);
//设置层级
node.level=this.level+1;
//设置父亲节点
node.parentNode=this;
}
public List<Node> getChilds() {
return this.childs;
}
/**
* 得到所有葉子節點
*
* @return
*/
public int getCountLeaf() {
if (this.countLeaf == 0) {
this.initCountLeaf();
}
return this.countLeaf;
}
/**
* 初始化所有叶子节点
*/
public void initCountLeaf() {
this.countLeaf=0;
if (this.isLeaf()) {
this.countLeaf = 1;
} else {
for (Node node : this.childs) {
this.countLeaf += node.getCountLeaf();
}
}
}
public int getLevel() {
return level;
}
/**
* 是不是叶子节点
*
* @return
*/
public boolean isLeaf() {
return this.childs == null || this.childs.size() < 1;
}
public Object getTarget() {
return this.targetObj;
}
public void setTarget(Object target) {
this.targetObj = target;
}
public String toString()
{
return this.targetObj.toString();
}
}
6 ExcelNode
复制代码
package com.aips.ps.excel;
import java.util.List;
/**
* 树形的excel节点实现
*
*/
public class ExcelNode extends Node {
protected static int startRow=0;//从地几行开始
protected static int startCell=0;//从地几列开始
private int rowNumber;
private int cellNumber;
private int rowFrom;
private int rowTo;
private int cellFrom;
private int cellTo;
public ExcelNode()
{
this(null);
}
public ExcelNode(Object target)
{
this.targetObj=target;
}
public void init(List<?> treeNodes) {
this.initCountLeaf();
this.initOther(treeNodes);
this.initChilds(treeNodes);
}
private void initChilds(List<?> treeNodes)
{
if(!this.isLeaf())
{
for (Node child : this.getChilds()) {
((ExcelNode)child).init(treeNodes);
}
}
}
protected void initOther(List<?> treeNodes) {
this.cellNumber=this.startCell+this.level;
this.rowNumber=this.parseRowNumber((List<Node>) treeNodes);
this.cellFrom=this.cellNumber;
this.cellTo=this.cellNumber;
this.rowFrom=this.rowNumber;
this.rowTo=this.rowNumber+this.getCountLeaf()-1;
}
/**
* 得到rowNumber
* @return
*/
private int parseRowNumber(List<Node> treeNodes) {
ExcelNode beforeNode=this.getBeforeNode(treeNodes);
if(null==beforeNode)
{
//沒有找到前面一个节点就是和父亲节点的开始行计算
return this.parentNode==null?this.startRow:((ExcelNode)this.parentNode).getRowFrom();
}else
{
//找到了前面一个节点 就是利用前面一个节点的rowTo+1
return beforeNode.getRowTo()+1;
}
}
/**
* 得到我前面一个节点
* @return
*/
protected ExcelNode getBeforeNode(List<Node> treeNodes) {
if(null==this.parentNode)
{
return getBeforeNodeDelegate(treeNodes);
}else
{
List<Node> nodes=this.parentNode.getChilds();
return getBeforeNodeDelegate(nodes);
}
}
private ExcelNode getBeforeNodeDelegate(List<Node> nodes)
{
if(nodes.size()<=1)
{
return null;
}
//如果第一个就是自己就没有前面的
if(this==nodes.get(0))
{
return null;
}
for (int i = 1; i < nodes.size(); i++) {
ExcelNode thisNode=(ExcelNode) nodes.get(i);
if(thisNode==this)
{
return (ExcelNode) nodes.get(i-1);
}
}
return null;
}
public int getRowFrom() {
return rowFrom;
}
public void setRowFrom(int rowFrom) {
this.rowFrom = rowFrom;
}
public int getRowTo() {
return rowTo;
}
public void setRowTo(int rowTo) {
this.rowTo = rowTo;
}
public int getCellFrom() {
return cellFrom;
}
public void setCellFrom(int cellFrom) {
this.cellFrom = cellFrom;
}
public int getCellTo() {
return cellTo;
}
public void setCellTo(int cellTo) {
this.cellTo = cellTo;
}
public int getRowNumber() {
return rowNumber;
}
public void setRowNumber(int rowNumber) {
this.rowNumber = rowNumber;
}
public int getCellNumber() {
return cellNumber;
}
public void setCellNumber(int cellNumber) {
this.cellNumber = cellNumber;
}
}