|
|
|
@ -0,0 +1,431 @@
|
|
|
|
|
package net.educoder.ecsonar.utils;
|
|
|
|
|
|
|
|
|
|
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
|
|
|
|
import org.apache.poi.ss.usermodel.*;
|
|
|
|
|
import org.apache.poi.ss.util.CellRangeAddress;
|
|
|
|
|
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
|
|
|
|
|
|
|
|
|
import java.io.*;
|
|
|
|
|
import java.util.*;
|
|
|
|
|
import java.util.regex.Matcher;
|
|
|
|
|
import java.util.regex.Pattern;
|
|
|
|
|
|
|
|
|
|
public class ExcelUtils {
|
|
|
|
|
|
|
|
|
|
//模板map
|
|
|
|
|
private Map<String, Workbook> tempWorkbook = new HashMap<String, Workbook>();
|
|
|
|
|
//模板输入流map
|
|
|
|
|
private Map<String, FileInputStream> tempStream = new HashMap<String, FileInputStream>();
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* <p class="detail">
|
|
|
|
|
* 描述:临时单元格数据
|
|
|
|
|
* </p>
|
|
|
|
|
*
|
|
|
|
|
* @author <a href="mailto:1435290472@qq.com">zq</a>
|
|
|
|
|
* @version V1.0
|
|
|
|
|
* @ClassName: Cell
|
|
|
|
|
* @date 2015年9月26日
|
|
|
|
|
*/
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* <p class="detail">
|
|
|
|
|
* 功能:按模板向Excel中相应地方填充数据
|
|
|
|
|
* </p>
|
|
|
|
|
*
|
|
|
|
|
* @param tempFilePath
|
|
|
|
|
* @param dataMap
|
|
|
|
|
* @param sheetNo
|
|
|
|
|
* @throws IOException
|
|
|
|
|
* @date 2015年9月26日
|
|
|
|
|
* @author <a href="mailto:1435290472@qq.com">zq</a>
|
|
|
|
|
*/
|
|
|
|
|
public void writeData(String tempFilePath, Map<String, Object> dataMap, int sheetNo) throws IOException {
|
|
|
|
|
//获取模板填充格式位置等数据
|
|
|
|
|
// HashMap tem = getTemp(tempFilePath,sheet);
|
|
|
|
|
//读取模板
|
|
|
|
|
Workbook wbModule = getTempWorkbook(tempFilePath);
|
|
|
|
|
//数据填充的sheet
|
|
|
|
|
Sheet wsheet = wbModule.getSheetAt(sheetNo);
|
|
|
|
|
|
|
|
|
|
Iterator it = dataMap.entrySet().iterator();
|
|
|
|
|
while (it.hasNext()) {
|
|
|
|
|
Map.Entry<String, Object> entry = (Map.Entry<String, Object>) it.next();
|
|
|
|
|
String point = entry.getKey();
|
|
|
|
|
Object data = entry.getValue();
|
|
|
|
|
|
|
|
|
|
TempCell cell = getCell(point, data, wsheet);
|
|
|
|
|
//指定坐标赋值
|
|
|
|
|
setCell(cell, wsheet);
|
|
|
|
|
}
|
|
|
|
|
//设置生成excel中公式自动计算
|
|
|
|
|
wsheet.setForceFormulaRecalculation(true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* <p class="detail">
|
|
|
|
|
* 功能:按模板向Excel中列表填充数据。 只支持列合并
|
|
|
|
|
* </p>
|
|
|
|
|
*
|
|
|
|
|
* @param tempFilePath
|
|
|
|
|
* @param heads 列表头部位置集合
|
|
|
|
|
* @param datalist
|
|
|
|
|
* @param sheetNo
|
|
|
|
|
* @throws FileNotFoundException
|
|
|
|
|
* @throws IOException
|
|
|
|
|
* @date 2015年9月27日
|
|
|
|
|
* @author <a href="mailto:1435290472@qq.com">zq</a>
|
|
|
|
|
*/
|
|
|
|
|
public void writeDateList(String tempFilePath, String[] heads, List<Map<Integer, Object>> datalist, int sheetNo) throws FileNotFoundException, IOException {
|
|
|
|
|
//读取模板
|
|
|
|
|
Workbook wbModule = getTempWorkbook(tempFilePath);
|
|
|
|
|
//数据填充的sheet
|
|
|
|
|
Sheet wsheet = wbModule.getSheetAt(sheetNo);
|
|
|
|
|
//列表数据模板cell
|
|
|
|
|
List<TempCell> tempCells = new ArrayList<TempCell>();
|
|
|
|
|
for (int i = 0; i < heads.length; i++) {
|
|
|
|
|
String point = heads[i];
|
|
|
|
|
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.setRow(tempCell.getRow() + 1);
|
|
|
|
|
tempCell.setData(dataMap.get(j + 1));
|
|
|
|
|
setCell(tempCell, wsheet);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* <p class="detail">
|
|
|
|
|
* 功能:获取输入工作区
|
|
|
|
|
* </p>
|
|
|
|
|
*
|
|
|
|
|
* @param tempFilePath
|
|
|
|
|
* @return
|
|
|
|
|
* @throws FileNotFoundException
|
|
|
|
|
* @throws IOException
|
|
|
|
|
* @date 2015年9月26日
|
|
|
|
|
* @author <a href="mailto:1435290472@qq.com">zq</a>
|
|
|
|
|
*/
|
|
|
|
|
private Workbook getTempWorkbook(String tempFilePath) throws FileNotFoundException, IOException {
|
|
|
|
|
if (!tempWorkbook.containsKey(tempFilePath)) {
|
|
|
|
|
if (tempFilePath.endsWith(".xlsx")) {
|
|
|
|
|
tempWorkbook.put(tempFilePath, new XSSFWorkbook(getFileInputStream(tempFilePath)));
|
|
|
|
|
} else if (tempFilePath.endsWith(".xls")) {
|
|
|
|
|
tempWorkbook.put(tempFilePath, new HSSFWorkbook(getFileInputStream(tempFilePath)));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return tempWorkbook.get(tempFilePath);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* <p class="detail">
|
|
|
|
|
* 功能:获得模板输入流
|
|
|
|
|
* </p>
|
|
|
|
|
*
|
|
|
|
|
* @param tempFilePath
|
|
|
|
|
* @return
|
|
|
|
|
* @throws FileNotFoundException
|
|
|
|
|
* @date 2015年9月26日
|
|
|
|
|
* @author <a href="mailto:1435290472@qq.com">zq</a>
|
|
|
|
|
*/
|
|
|
|
|
private FileInputStream getFileInputStream(String tempFilePath) throws FileNotFoundException {
|
|
|
|
|
if (!tempStream.containsKey(tempFilePath)) {
|
|
|
|
|
tempStream.put(tempFilePath, new FileInputStream(tempFilePath));
|
|
|
|
|
}
|
|
|
|
|
return tempStream.get(tempFilePath);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* <p class="detail">
|
|
|
|
|
* 功能:设置单元格数据,样式 (根据坐标:B3)
|
|
|
|
|
* </p>
|
|
|
|
|
*
|
|
|
|
|
* @param point
|
|
|
|
|
* @param data
|
|
|
|
|
* @param sheet
|
|
|
|
|
* @return
|
|
|
|
|
* @date 2015年9月27日
|
|
|
|
|
* @author <a href="mailto:1435290472@qq.com">zq</a>
|
|
|
|
|
*/
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* <p class="detail">
|
|
|
|
|
* 功能:给指定坐标赋值
|
|
|
|
|
* </p>
|
|
|
|
|
*
|
|
|
|
|
* @param tempCell
|
|
|
|
|
* @param sheet
|
|
|
|
|
* @date 2015年9月27日
|
|
|
|
|
* @author <a href="mailto:1435290472@qq.com">zq</a>
|
|
|
|
|
*/
|
|
|
|
|
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) {
|
|
|
|
|
rowIn = sheet.createRow(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());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* <p class="detail">
|
|
|
|
|
* 功能:写到输出流并移除资源
|
|
|
|
|
* </p>
|
|
|
|
|
*
|
|
|
|
|
* @param tempFilePath
|
|
|
|
|
* @param os
|
|
|
|
|
* @throws FileNotFoundException
|
|
|
|
|
* @throws IOException
|
|
|
|
|
* @date 2015年9月27日
|
|
|
|
|
* @author <a href="mailto:1435290472@qq.com">zq</a>
|
|
|
|
|
*/
|
|
|
|
|
public void writeAndClose(String tempFilePath, OutputStream os) throws FileNotFoundException, IOException {
|
|
|
|
|
if (getTempWorkbook(tempFilePath) != null) {
|
|
|
|
|
getTempWorkbook(tempFilePath).write(os);
|
|
|
|
|
tempWorkbook.remove(tempFilePath);
|
|
|
|
|
}
|
|
|
|
|
if (getFileInputStream(tempFilePath) != null) {
|
|
|
|
|
getFileInputStream(tempFilePath).close();
|
|
|
|
|
tempStream.remove(tempFilePath);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* <p class="detail">
|
|
|
|
|
* 功能:判断指定的单元格是否是合并单元格
|
|
|
|
|
* </p>
|
|
|
|
|
*
|
|
|
|
|
* @param sheet
|
|
|
|
|
* @param row
|
|
|
|
|
* @param column
|
|
|
|
|
* @return 0:不是合并单元格,i:合并单元格的位置
|
|
|
|
|
* @date 2015年9月27日
|
|
|
|
|
* @author <a href="mailto:1435290472@qq.com">zq</a>
|
|
|
|
|
*/
|
|
|
|
|
private Integer isMergedRegion(Sheet sheet, int row, int column) {
|
|
|
|
|
int sheetMergeCount = sheet.getNumMergedRegions();
|
|
|
|
|
for (int i = 0; i < sheetMergeCount; 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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* <p class="detail">
|
|
|
|
|
* 功能:合并单元格
|
|
|
|
|
* </p>
|
|
|
|
|
*
|
|
|
|
|
* @param sheet
|
|
|
|
|
* @param firstRow
|
|
|
|
|
* @param lastRow
|
|
|
|
|
* @param firstCol
|
|
|
|
|
* @param lastCol
|
|
|
|
|
* @date 2015年9月27日
|
|
|
|
|
* @author <a href="mailto:1435290472@qq.com">zq</a>
|
|
|
|
|
*/
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* <p class="detail">
|
|
|
|
|
* 功能:设置合并单元格样式
|
|
|
|
|
* </p>
|
|
|
|
|
*
|
|
|
|
|
* @param cs
|
|
|
|
|
* @param region
|
|
|
|
|
* @param sheet
|
|
|
|
|
* @date 2015年9月27日
|
|
|
|
|
* @author <a href="mailto:1435290472@qq.com">zq</a>
|
|
|
|
|
*/
|
|
|
|
|
private static 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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static void main(String[] args) throws FileNotFoundException, IOException {
|
|
|
|
|
String tempFilePath = ExcelUtil.class.getClassLoader().getResource("template1.xlsx").getPath();
|
|
|
|
|
// String tempFilePath = "D:/demo.xlsx";
|
|
|
|
|
File file = new File("/Users/youyongsheng/Desktop/data.xlsx");
|
|
|
|
|
OutputStream os = new FileOutputStream(file);
|
|
|
|
|
|
|
|
|
|
ExcelUtils excel = new ExcelUtils();
|
|
|
|
|
Map<String, Object> dataMap = new HashMap<String, Object>();
|
|
|
|
|
excel.writeData(tempFilePath, dataMap, 0);
|
|
|
|
|
|
|
|
|
|
List<Map<Integer, Object>> datalist = new ArrayList<Map<Integer, Object>>();
|
|
|
|
|
Map<Integer, Object> data = new HashMap<Integer, Object>();
|
|
|
|
|
data.put(1, "defff");
|
|
|
|
|
data.put(2, "男1");
|
|
|
|
|
data.put(3, 45);
|
|
|
|
|
data.put(4, 111);
|
|
|
|
|
datalist.add(data);
|
|
|
|
|
data.put(1, "hhhhhh");
|
|
|
|
|
data.put(2, "男2");
|
|
|
|
|
data.put(3, 46);
|
|
|
|
|
data.put(4, 222);
|
|
|
|
|
datalist.add(data);
|
|
|
|
|
String[] heads = new String[]{"A5", "C5", "E5","D5"}; //必须为列表头部所有位置集合, 输出 数据单元格样式和头部单元格样式保持一致
|
|
|
|
|
excel.writeDateList(tempFilePath, heads, datalist, 0);
|
|
|
|
|
|
|
|
|
|
//写到输出流并移除资源
|
|
|
|
|
excel.writeAndClose(tempFilePath, os);
|
|
|
|
|
|
|
|
|
|
os.flush();
|
|
|
|
|
os.close();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|