需要预先新建编辑好一个excel文件,设置好样式。

编辑好输出的数据,根据excel坐标一一对应。

支持列表数据输出,列表中列合并。

代码如下:

package com.icourt.util;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress; import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern; /**
* 描述:poi根据模板导出excel,根据excel坐标赋值,如(B1)
*/
public class ExcelExportUtil { //模板map
private Map<String, Workbook> tempWorkbook = new HashMap<String, Workbook>();
//模板输入流map
private Map<String, InputStream> tempStream = new HashMap<String, InputStream>(); /**
* 功能:按模板向Excel中相应地方填充数据
*/
public void writeData(String templateFilePath, Map<String, Object> dataMap, int sheetNo) throws IOException, InvalidFormatException {
if (dataMap == null || dataMap.isEmpty()) {
return;
}
//读取模板
Workbook wbModule = getTempWorkbook(templateFilePath);
//数据填充的sheet
Sheet wsheet = wbModule.getSheetAt(sheetNo); for (Entry<String, Object> entry : dataMap.entrySet()) {
String point = entry.getKey();
Object data = entry.getValue(); TempCell cell = getCell(point, data, wsheet);
//指定坐标赋值
setCell(cell, wsheet);
} //设置生成excel中公式自动计算
wsheet.setForceFormulaRecalculation(true);
} /**
* 功能:按模板向Excel中列表填充数据.只支持列合并
*/
public void writeDateList(String templateFilePath, String[] heads, List<Map<Integer, Object>> datalist, int sheetNo) throws IOException, InvalidFormatException {
if (heads == null || heads.length <= 0 || CollectionUtils.isEmpty(datalist)) {
return;
}
//读取模板
Workbook wbModule = getTempWorkbook(templateFilePath);
//数据填充的sheet
Sheet wsheet = wbModule.getSheetAt(sheetNo); //列表数据模板cell
List<TempCell> tempCells = new ArrayList<TempCell>(heads.length);
for (String point : heads) {
TempCell tempCell = getCell(point, null, wsheet);
//取得合并单元格位置 -1:表示不是合并单元格
int pos = isMergedRegion(wsheet, tempCell.getRow(), tempCell.getColumn());
if (pos > -1) {
CellRangeAddress range = wsheet.getMergedRegion(pos);
tempCell.setColumnSize(range.getLastColumn() - range.getFirstColumn());
}
tempCells.add(tempCell);
}
//赋值
for (int i = 0; i < datalist.size(); i++) {//数据行
Map<Integer, Object> dataMap = datalist.get(i);
for (int j = 0; j < tempCells.size(); j++) {//列
TempCell tempCell = tempCells.get(j);
tempCell.setData(dataMap.get(j + 1));
setCell(tempCell, wsheet);
tempCell.setRow(tempCell.getRow() + 1);
}
}
} /**
* 功能:获取输入工作区
*/
private Workbook getTempWorkbook(String templateFilePath) throws IOException, InvalidFormatException {
if (!tempWorkbook.containsKey(templateFilePath)) {
InputStream inputStream = getInputStream(templateFilePath);
tempWorkbook.put(templateFilePath, WorkbookFactory.create(inputStream));
}
return tempWorkbook.get(templateFilePath);
} /**
* 功能:获得模板输入流
*/
private InputStream getInputStream(String templateFilePath) throws FileNotFoundException {
if (!tempStream.containsKey(templateFilePath)) {
tempStream.put(templateFilePath, new FileInputStream((templateFilePath)));
}
return tempStream.get(templateFilePath);
} /**
* 功能:获取单元格数据,样式(根据坐标:B3)
*/
private TempCell getCell(String point, Object data, Sheet sheet) {
TempCell tempCell = new TempCell(); //得到列 字母
String lineStr = "";
String reg = "[A-Z]+";
Pattern p = Pattern.compile(reg);
Matcher m = p.matcher(point);
while (m.find()) {
lineStr = m.group();
}
//将列字母转成列号 根据ascii转换
char[] ch = lineStr.toCharArray();
int column = 0;
for (int i = 0; i < ch.length; i++) {
char c = ch[i];
int post = ch.length - i - 1;
int r = (int) Math.pow(10, post);
column = column + r * ((int) c - 65);
}
tempCell.setColumn(column); //得到行号
reg = "[1-9]+";
p = Pattern.compile(reg);
m = p.matcher(point);
while (m.find()) {
tempCell.setRow((Integer.parseInt(m.group()) - 1));
} //获取模板指定单元格样式,设置到tempCell(写列表数据的时候用)
Row rowIn = sheet.getRow(tempCell.getRow());
if (rowIn == null) {
rowIn = sheet.createRow(tempCell.getRow());
}
Cell cellIn = rowIn.getCell(tempCell.getColumn());
if (cellIn == null) {
cellIn = rowIn.createCell(tempCell.getColumn());
}
tempCell.setCellStyle(cellIn.getCellStyle());
tempCell.setData(data);
return tempCell;
} /**
* 功能:给指定坐标单元格赋值
*/
private void setCell(TempCell tempCell, Sheet sheet) {
if (tempCell.getColumnSize() > -1) {
CellRangeAddress rangeAddress = mergeRegion(sheet, tempCell.getRow(), tempCell.getRow(), tempCell.getColumn(), tempCell.getColumn() + tempCell.getColumnSize());
setRegionStyle(tempCell.getCellStyle(), rangeAddress, sheet);
} Row rowIn = sheet.getRow(tempCell.getRow());
if (rowIn == null) {
copyRows(tempCell.getRow() - 1, tempCell.getRow() - 1, tempCell.getRow(), sheet);//复制上一行
rowIn = sheet.getRow(tempCell.getRow());
}
Cell cellIn = rowIn.getCell(tempCell.getColumn());
if (cellIn == null) {
cellIn = rowIn.createCell(tempCell.getColumn());
}
//根据data类型给cell赋值
if (tempCell.getData() instanceof String) {
cellIn.setCellValue((String) tempCell.getData());
} else if (tempCell.getData() instanceof Integer) {
cellIn.setCellValue((int) tempCell.getData());
} else if (tempCell.getData() instanceof Double) {
cellIn.setCellValue((double) tempCell.getData());
} else {
cellIn.setCellValue((String) tempCell.getData());
}
//样式
if (tempCell.getCellStyle() != null && tempCell.getColumnSize() == -1) {
cellIn.setCellStyle(tempCell.getCellStyle());
}
} /**
* 功能:写到输出流并移除资源
*/
public void writeAndClose(String templateFilePath, OutputStream os) throws IOException, InvalidFormatException {
if (getTempWorkbook(templateFilePath) != null) {
getTempWorkbook(templateFilePath).write(os);
tempWorkbook.remove(templateFilePath);
}
if (getInputStream(templateFilePath) != null) {
getInputStream(templateFilePath).close();
tempStream.remove(templateFilePath);
}
} /**
* 功能:判断指定的单元格是否是合并单元格
*/
private Integer isMergedRegion(Sheet sheet, int row, int column) {
for (int i = 0; i < sheet.getNumMergedRegions(); i++) {
CellRangeAddress range = sheet.getMergedRegion(i);
int firstColumn = range.getFirstColumn();
int lastColumn = range.getLastColumn();
int firstRow = range.getFirstRow();
int lastRow = range.getLastRow();
if (row >= firstRow && row <= lastRow) {
if (column >= firstColumn && column <= lastColumn) {
return i;
}
}
}
return -1;
} /**
* 功能:合并单元格
*/
private CellRangeAddress mergeRegion(Sheet sheet, int firstRow, int lastRow, int firstCol, int lastCol) {
CellRangeAddress rang = new CellRangeAddress(firstRow, lastRow, firstCol, lastCol);
sheet.addMergedRegion(rang);
return rang;
} /**
* 功能:设置合并单元格样式
*/
private void setRegionStyle(CellStyle cs, CellRangeAddress region, Sheet sheet) {
for (int i = region.getFirstRow(); i <= region.getLastRow(); i++) {
Row row = sheet.getRow(i);
if (row == null) row = sheet.createRow(i);
for (int j = region.getFirstColumn(); j <= region.getLastColumn(); j++) {
Cell cell = row.getCell(j);
if (cell == null) {
cell = row.createCell(j);
cell.setCellValue("");
}
cell.setCellStyle(cs);
}
}
} /**
* 功能:copy rows
*/
private void copyRows(int startRow, int endRow, int pPosition, Sheet sheet) {
int pStartRow = startRow - 1;
int pEndRow = endRow - 1;
int targetRowFrom;
int targetRowTo;
int columnCount;
CellRangeAddress region = null;
int i;
int j;
if (pStartRow == -1 || pEndRow == -1) {
return;
}
// 拷贝合并的单元格
for (i = 0; i < sheet.getNumMergedRegions(); i++) {
region = sheet.getMergedRegion(i);
if ((region.getFirstRow() >= pStartRow)
&& (region.getLastRow() <= pEndRow)) {
targetRowFrom = region.getFirstRow() - pStartRow + pPosition;
targetRowTo = region.getLastRow() - pStartRow + pPosition;
CellRangeAddress newRegion = region.copy();
newRegion.setFirstRow(targetRowFrom);
newRegion.setFirstColumn(region.getFirstColumn());
newRegion.setLastRow(targetRowTo);
newRegion.setLastColumn(region.getLastColumn());
sheet.addMergedRegion(newRegion);
}
}
// 设置列宽
for (i = pStartRow; i <= pEndRow; i++) {
Row sourceRow = sheet.getRow(i);
columnCount = sourceRow.getLastCellNum();
if (sourceRow != null) {
Row newRow = sheet.createRow(pPosition - pStartRow + i);
newRow.setHeight(sourceRow.getHeight());
for (j = 0; j < columnCount; j++) {
Cell templateCell = sourceRow.getCell(j);
if (templateCell != null) {
Cell newCell = newRow.createCell(j);
copyCell(templateCell, newCell);
}
}
}
}
} /**
* 功能:copy cell,不copy值
*/
private void copyCell(Cell srcCell, Cell distCell) {
distCell.setCellStyle(srcCell.getCellStyle());
if (srcCell.getCellComment() != null) {
distCell.setCellComment(srcCell.getCellComment());
}
int srcCellType = srcCell.getCellType();
distCell.setCellType(srcCellType);
} /**
* 描述:临时单元格数据
*/
class TempCell {
private int row;
private int column;
private CellStyle cellStyle;
private Object data;
//用于列表合并,表示几列合并
private int columnSize = -1; public int getColumn() {
return column;
} public void setColumn(int column) {
this.column = column;
} public int getRow() {
return row;
} public void setRow(int row) {
this.row = row;
} public CellStyle getCellStyle() {
return cellStyle;
} public void setCellStyle(CellStyle cellStyle) {
this.cellStyle = cellStyle;
} public Object getData() {
return data;
} public void setData(Object data) {
this.data = data;
} public int getColumnSize() {
return columnSize;
} public void setColumnSize(int columnSize) {
this.columnSize = columnSize;
}
} public static void main(String[] args) throws FileNotFoundException, IOException, InvalidFormatException {
String templateFilePath = ExcelExportUtil.class.getClassLoader().getResource("plugin/ProTiming.xlsx").getPath();
File file = new File("/Users/sql/Downloads/test/data.xlsx");
OutputStream os = new FileOutputStream(file); ExcelExportUtil excel = new ExcelExportUtil();
Map<String, Object> dataMap = new HashMap<String, Object>();
dataMap.put("B1", "03_Alpha_项目工作时间统计表");
dataMap.put("B2", "统计时间:2017/01/01 - 2017/03/31"); excel.writeData(templateFilePath, dataMap, 0); List<Map<Integer, Object>> datalist = new ArrayList<Map<Integer, Object>>();
Map<Integer, Object> data = new HashMap<Integer, Object>();
data.put(1, "3/10/17");
data.put(2, "18:50");
data.put(3, "19:00");
data.put(4, "李子鹏");
data.put(5, "新增项目键值对接口,供任务计时调用");
data.put(6, "代码开发");
data.put(7, "3.17"); datalist.add(data);
data = new HashMap<Integer, Object>();
data.put(1, "3/10/17");
data.put(2, "18:50");
data.put(3, "19:00");
data.put(4, "李子鹏");
data.put(5, "新增项目键值对接口,供任务计时调用");
data.put(6, "代码开发");
data.put(7, "3.17");
datalist.add(data);
data = new HashMap<Integer, Object>();
data.put(1, "3/10/17");
data.put(2, "18:50");
data.put(3, "19:00");
data.put(4, "李子鹏");
data.put(5, "新增项目键值对接口,供任务计时调用");
data.put(6, "代码开发");
data.put(7, "3.17");
datalist.add(data);
data = new HashMap<Integer, Object>();
data.put(1, "3/10/17");
data.put(2, "18:50");
data.put(3, "19:00");
data.put(4, "李子鹏");
data.put(5, "新增项目键值对接口,供任务计时调用");
data.put(6, "代码开发");
data.put(7, "3.17");
datalist.add(data);
data = new HashMap<Integer, Object>();
data.put(1, "3/10/17");
data.put(2, "18:50");
data.put(3, "19:00");
data.put(4, "李子鹏");
data.put(5, "新增项目键值对接口,供任务计时调用");
data.put(6, "代码开发");
data.put(7, "3.17");
datalist.add(data);
data = new HashMap<Integer, Object>();
data.put(1, "3/10/17");
data.put(2, "18:50");
data.put(3, "19:00");
data.put(4, "李子鹏");
data.put(5, "新增项目键值对接口,供任务计时调用");
data.put(6, "代码开发");
data.put(7, "3.17");
datalist.add(data);
data = new HashMap<Integer, Object>();
data.put(1, "3/10/17");
data.put(2, "18:50");
data.put(3, "19:00");
data.put(4, "李子鹏");
data.put(5, "新增项目键值对接口,供任务计时调用");
data.put(6, "代码开发");
data.put(7, "3.17");
datalist.add(data);
data = new HashMap<Integer, Object>();
data.put(1, "3/10/17");
data.put(2, "18:50");
data.put(3, "19:00");
data.put(4, "李子鹏");
data.put(5, "新增项目键值对接口,供任务计时调用");
data.put(6, "代码开发");
data.put(7, "3.17");
datalist.add(data); data = new HashMap<Integer, Object>();
data.put(1, "3/10/17");
data.put(2, "18:50");
data.put(3, "19:00");
data.put(4, "李子鹏");
data.put(5, "新增项目键值对接口,供任务计时调用新增项目键值对接口,供任务计时调用新增项目键值对接口,供任务计时调用新增项目键值对接口,供任务计时调用新增项目键值对接口,供任务计时调用新增项目键值对接口,供任务计时调用新增项目键值对接口,供任务计时调用新增项目键值对接口,供任务计时调用");
data.put(6, "代码开发");
data.put(7, "3.17");
datalist.add(data);
data = new HashMap<Integer, Object>();
data.put(1, "");
data.put(2, "");
data.put(3, "");
data.put(4, "");
data.put(5, "");
data.put(6, "");
data.put(7, "");
datalist.add(data); String[] heads = new String[]{"B4", "C4", "D4", "E4", "F4", "G4", "H4"};
excel.writeDateList(templateFilePath, heads, datalist, 0); //写到输出流并移除资源
excel.writeAndClose(templateFilePath, os); os.flush();
os.close();
} }

大体思路:

最主要是制作好模版

代码根据模版,读取设置好的列的格式,在循环数据行,读取模版中的对应的行,存在该行就取得,不存在看是否需要copy某一行,不需要就手动创建无制定格式的行,后面在为该行的每一列对应的给个单元格制定格式和数据。

apache poi根据模板导出excel的更多相关文章

  1. POI通过模板导出EXCEL文件

    一般的EXCEL导出使用POI先创建一个HSSFWorkbook,然后通过不断创建HSSFRow,HSSFCell后设置单元格内容便可以完成导出. 这次在项目中需要用到模板,导出的内容包括(1.模板中 ...

  2. 使用Apache poi来编写导出excel的工具类

    在JavaWeb开发的需求中,我们会经常看到导出excel的功能需求,然后java并没有提供操作office文档的功能,这个时候我们就需要使用额外的组件来帮助我们完成这项功能了. 很高兴Apache基 ...

  3. java后台poi根据模板导出excel

    public class ExcelUtils { private static final String INSPECTIONRECORD_SURFACE_TEMPLET_PATH = " ...

  4. poi根据excel模板导出Excel

    /****单元格值对象**/public class Cells { /*** * 行 */ private int row; /** * 列 */ private int column; /** * ...

  5. Java无模板导出Excel,Apache-POI插件实现

    开发环境 jdk 1.8 Maven 3.6 Tomcat 8.5 SpringBoot 2.1.4.RELEASE Apache-POI 3.6 Idea 注意: 我是在现有的基于SpringBoo ...

  6. Java中使用poi导入、导出Excel

    一.介绍 当前B/S模式已成为应用开发的主流,而在企业办公系统中,常常有客户这样子要求:你要把我们的报表直接用Excel打开(电信系统.银行系统).或者是:我们已经习惯用Excel打印.这样在我们实际 ...

  7. Java使用POI实现数据导出excel报表

    Java使用POI实现数据导出excel报表 在上篇文章中,我们简单介绍了java读取word,excel和pdf文档内容 ,但在实际开发中,我们用到最多的是把数据库中数据导出excel报表形式.不仅 ...

  8. POI导入和导出Excel总结

    POI导入和导出Excel总结   POI使用总结 1.POI读取Excel 打开工作簿的方式有以下两种简单的应用,POI读取和输出工作簿文件都可以通过以下两种方式来声明: //通过输入流的方式打开本 ...

  9. aspose.cells根据模板导出excel

    又隔十多天没写博客了,最近都在忙项目的事情,公司人事变动也比较大,手头上就又多了一个项目.最近做用aspose.cells根据模板导出excel报价单的功能,顺便把相关的核心记下来,先上模板和导出的效 ...

随机推荐

  1. 毕业设计 python opencv实现车牌识别 码云地址

    码云地址:https://gitee.com/yinghualuowu/Python_VLPR 删除了冗余代码,可以更加便于运行.其实是为了那些进不去github准备的~

  2. [水题AC乐] - 贪心

    HDU - 1009 https://paste.ubuntu.com/p/rgSYpSKkwW/ POJ - 1017 麻烦的模拟 贪心 题意就是用尽量少的66h箱子装nnh的物品,贪心策略很明显, ...

  3. http简单请求 -- 复杂请求

  4. [转] CSS 颜色名

    [From] http://www.w3school.com.cn/cssref/css_colornames.asp CSS 颜色名 所有浏览器都支持的颜色名. HTML 和 CSS 颜色规范中定义 ...

  5. Oracle之UTL_FILE 包用法详解

    [转自] http://zhangzhongjie.iteye.com/blog/1903024 UTL_FILE包可以用来读写操作系统上的文本文件,UTL_FILE提供了在客户端(FORM等等)和服 ...

  6. js 中 forEach 和 map

    共同点: 1.都是循环遍历数组中的每一项. 2.forEach() 和 map() 里面每一次执行匿名函数都支持3个参数:数组中的当前项item,当前项的索引index,原始数组input. 3.匿名 ...

  7. js数组方法详解

    Array对象的方法-25个 /*js数组方法详解 */ /* * 1 concat() 用于连接多个数组或者值-------------- * 2 copyWithin() 方法用于从数组的指定位置 ...

  8. C# 判读取得字符编码格式

    FileStream fs1 = new FileStream(folder + strPath, FileMode.Open); byte[] bytes = new byte[fs1.Length ...

  9. Best HTTP

    http://blog.csdn.net/u012322710/article/details/52860747 Best HTTP (Pro)  这是一款很多公司都在用的网页插件,感觉确实不错,分P ...

  10. pat09-散列3. Hashing - Hard Version (30)

    09-散列3. Hashing - Hard Version (30) 时间限制 200 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 HE, Qin ...