Procházet zdrojové kódy

几个常用表达式的支持,列的删除

4.1.3.A
jueyue před 10 roky
rodič
revize
0e2fa07a85
7 změnil soubory, kde provedl 243 přidání a 76 odebrání
  1. +12
    -0
      easypoi-base/src/main/java/org/jeecgframework/poi/excel/entity/TemplateExportParams.java
  2. +117
    -66
      easypoi-base/src/main/java/org/jeecgframework/poi/excel/export/template/ExcelExportOfTemplateUtil.java
  3. +12
    -7
      easypoi-base/src/main/java/org/jeecgframework/poi/util/PoiElUtil.java
  4. +8
    -3
      easypoi-base/src/main/java/org/jeecgframework/poi/util/PoiPublicUtil.java
  5. +90
    -0
      easypoi-base/src/main/java/org/jeecgframework/poi/util/PoiSheetUtility.java
  6. binární
      easypoi-test/src/main/java/org/jeecgframework/poi/test/excel/doc/foreach.xlsx
  7. +4
    -0
      easypoi-test/src/main/java/org/jeecgframework/poi/test/excel/template/TemplateForEachTest.java

+ 12
- 0
easypoi-base/src/main/java/org/jeecgframework/poi/excel/entity/TemplateExportParams.java Zobrazit soubor

@@ -47,6 +47,10 @@ public class TemplateExportParams extends ExcelBaseParams {
* Excel 导出style
*/
private Class<?> style = ExcelExportStylerDefaultImpl.class;
/**
* FOR EACH 用到的局部变量
*/
private String tempParams = "t";
/**
* 默认构造器
@@ -168,4 +172,12 @@ public class TemplateExportParams extends ExcelBaseParams {
this.scanAllsheet = scanAllsheet;
}
public String getTempParams() {
return tempParams;
}
public void setTempParams(String tempParams) {
this.tempParams = tempParams;
}
}

+ 117
- 66
easypoi-base/src/main/java/org/jeecgframework/poi/excel/export/template/ExcelExportOfTemplateUtil.java Zobrazit soubor

@@ -27,7 +27,11 @@ import org.jeecgframework.poi.excel.export.base.ExcelExportBase;
import org.jeecgframework.poi.excel.export.styler.IExcelExportStyler;
import org.jeecgframework.poi.exception.excel.ExcelExportException;
import org.jeecgframework.poi.exception.excel.enums.ExcelExportEnum;
import static org.jeecgframework.poi.util.PoiElUtil.*;
import org.jeecgframework.poi.util.PoiPublicUtil;
import org.jeecgframework.poi.util.PoiSheetUtility;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -40,34 +44,34 @@ import org.slf4j.LoggerFactory;
*/
public final class ExcelExportOfTemplateUtil extends ExcelExportBase {
private static final Logger LOGGER = LoggerFactory
.getLogger(ExcelExportOfTemplateUtil.class);
private static final Logger LOGGER = LoggerFactory
.getLogger(ExcelExportOfTemplateUtil.class);
private static final String START_STR = "{{";
private static final String END_STR = "}}";
private static final String NUMBER_SYMBOL = "N:";
/**
* 缓存TEMP 的for each创建的cell ,跳过这个cell的模板语法查找,提高效率
*/
private Set<String> tempCreateCellSet = new HashSet<String>();
private Set<String> tempCreateCellSet = new HashSet<String>();
/**
* 模板参数,全局都用到
*/
private TemplateExportParams teplateParams;
/**
* 往Sheet 填充正常数据,根据表头信息 使用导入的部分逻辑,坐对象映射
*
* @param params
* @param teplateParams
* @param pojoClass
* @param dataSet
* @param workbook
*/
private void addDataToSheet(TemplateExportParams params, Class<?> pojoClass,
Collection<?> dataSet, Sheet sheet, Workbook workbook)
throws Exception {
private void addDataToSheet(Class<?> pojoClass, Collection<?> dataSet, Sheet sheet,
Workbook workbook) throws Exception {
if (workbook instanceof XSSFWorkbook) {
super.type = ExcelType.XSSF;
}
// 获取表头数据
Map<String, Integer> titlemap = getTitleMap(params, sheet);
Map<String, Integer> titlemap = getTitleMap(sheet);
Drawing patriarch = sheet.createDrawingPatriarch();
// 得到所有字段
Field[] fileds = PoiPublicUtil.getClassFields(pojoClass);
@@ -77,17 +81,17 @@ public final class ExcelExportOfTemplateUtil extends ExcelExportBase {
targetId = etarget.value();
}
// 创建表格样式
setExcelExportStyler((IExcelExportStyler) params.getStyle().getConstructor(Workbook.class)
.newInstance(workbook));
setExcelExportStyler((IExcelExportStyler) teplateParams.getStyle()
.getConstructor(Workbook.class).newInstance(workbook));
// 获取实体对象的导出数据
List<ExcelExportEntity> excelParams = new ArrayList<ExcelExportEntity>();
getAllExcelField(null, targetId, fileds, excelParams, pojoClass, null);
// 根据表头进行筛选排序
sortAndFilterExportField(excelParams, titlemap);
short rowHeight = getRowHeight(excelParams);
int index = params.getHeadingRows() + params.getHeadingStartRow(), titleHeight = index;
int index = teplateParams.getHeadingRows() + teplateParams.getHeadingStartRow(), titleHeight = index;
//下移数据,模拟插入
sheet.shiftRows(params.getHeadingRows() + params.getHeadingStartRow(),
sheet.shiftRows(teplateParams.getHeadingRows() + teplateParams.getHeadingStartRow(),
sheet.getLastRowNum(), getShiftRows(dataSet, excelParams), true, true);
if (excelParams.size() == 0) {
return;
@@ -150,7 +154,8 @@ public final class ExcelExportOfTemplateUtil extends ExcelExportBase {
Workbook wb = null;
// step 2. 判断模板的Excel类型,解析模板
try {
wb = getCloneWorkBook(params);
this.teplateParams = params;
wb = getCloneWorkBook();
// step 3. 解析模板
for (int i = 0, le = params.isScanAllsheet() ? wb.getNumberOfSheets() : params
.getSheetNum().length; i < le; i++) {
@@ -166,8 +171,7 @@ public final class ExcelExportOfTemplateUtil extends ExcelExportBase {
if (dataHanlder != null) {
needHanlderList = Arrays.asList(dataHanlder.getNeedHandlerFields());
}
addDataToSheet(params, pojoClass, dataSet, wb.getSheetAt(params.getDataSheetNum()),
wb);
addDataToSheet(pojoClass, dataSet, wb.getSheetAt(params.getDataSheetNum()), wb);
}
} catch (Exception e) {
LOGGER.error(e.getMessage(), e);
@@ -179,46 +183,30 @@ public final class ExcelExportOfTemplateUtil extends ExcelExportBase {
/**
* 克隆excel防止操作原对象,workbook无法克隆,只能对excel进行克隆
*
* @param params
* @param teplateParams
* @throws Exception
* @Author JueYue
* @date 2013-11-11
*/
private Workbook getCloneWorkBook(TemplateExportParams params) throws Exception {
return ExcelCache.getWorkbook(params.getTemplateUrl(), params.getSheetNum(),
params.isScanAllsheet());
}
private Workbook getCloneWorkBook() throws Exception {
return ExcelCache.getWorkbook(teplateParams.getTemplateUrl(), teplateParams.getSheetNum(),
teplateParams.isScanAllsheet());
/**
* 获取参数值
*
* @param params
* @param map
* @return
*/
private String getParamsValue(String params, Map<String, Object> map) throws Exception {
if (params.indexOf(".") != -1) {
String[] paramsArr = params.split("\\.");
return String
.valueOf(PoiPublicUtil.getValueDoWhile(map.get(paramsArr[0]), paramsArr, 1));
}
return map.containsKey(params) ? map.get(params).toString() : "";
}
/**
* 获取表头数据,设置表头的序号
*
* @param params
* @param teplateParams
* @param sheet
* @return
*/
private Map<String, Integer> getTitleMap(TemplateExportParams params, Sheet sheet) {
private Map<String, Integer> getTitleMap(Sheet sheet) {
Row row = null;
Iterator<Cell> cellTitle;
Map<String, Integer> titlemap = new HashMap<String, Integer>();
for (int j = 0; j < params.getHeadingRows(); j++) {
row = sheet.getRow(j + params.getHeadingStartRow());
for (int j = 0; j < teplateParams.getHeadingRows(); j++) {
row = sheet.getRow(j + teplateParams.getHeadingStartRow());
cellTitle = row.cellIterator();
int i = row.getFirstCellNum();
while (cellTitle.hasNext()) {
@@ -235,10 +223,14 @@ public final class ExcelExportOfTemplateUtil extends ExcelExportBase {
}
private void parseTemplate(Sheet sheet, Map<String, Object> map) throws Exception {
deleteCell(sheet, map);
Row row = null;
int index = 0;
while (index <= sheet.getLastRowNum()) {
row = sheet.getRow(index++);
if (row == null) {
continue;
}
for (int i = row.getFirstCellNum(); i < row.getLastCellNum(); i++) {
if (row.getCell(i) != null
&& !tempCreateCellSet.contains(row.getRowNum() + "_"
@@ -249,6 +241,40 @@ public final class ExcelExportOfTemplateUtil extends ExcelExportBase {
}
}
/**
* 先判断删除,省得影响效率
* @param sheet
* @param map
* @throws Exception
*/
private void deleteCell(Sheet sheet, Map<String, Object> map) throws Exception {
Row row = null;
Cell cell = null;
int index = 0;
while (index <= sheet.getLastRowNum()) {
row = sheet.getRow(index++);
if (row == null) {
continue;
}
for (int i = row.getFirstCellNum(); i < row.getLastCellNum(); i++) {
cell = row.getCell(i);
if (row.getCell(i) != null
&& (cell.getCellType() == Cell.CELL_TYPE_STRING || cell.getCellType() == Cell.CELL_TYPE_NUMERIC)) {
cell.setCellType(Cell.CELL_TYPE_STRING);
String text = cell.getStringCellValue();
if (text.contains(IF_DELETE)) {
if (Boolean.valueOf(eval(
text.substring(text.indexOf(START_STR) + 2, text.indexOf(END_STR))
.trim(), map).toString())) {
PoiSheetUtility.deleteColumn(sheet, i);
}
cell.setCellValue("");
}
}
}
}
}
/**
* 给每个Cell通过解析方式set值
*
@@ -263,12 +289,11 @@ public final class ExcelExportOfTemplateUtil extends ExcelExportBase {
String oldString;
cell.setCellType(Cell.CELL_TYPE_STRING);
oldString = cell.getStringCellValue();
if (oldString != null && oldString.indexOf(START_STR) != -1
&& !oldString.contains("foreach||")) {
if (oldString != null && oldString.indexOf(START_STR) != -1 && !oldString.contains(FOREACH)) {
// step 2. 判断是否含有解析函数
String params;
String params = null;
boolean isNumber = false;
if (oldString.contains(NUMBER_SYMBOL)) {
if (isNumber(oldString)) {
isNumber = true;
oldString = oldString.replace(NUMBER_SYMBOL, "");
}
@@ -276,8 +301,8 @@ public final class ExcelExportOfTemplateUtil extends ExcelExportBase {
params = oldString.substring(oldString.indexOf(START_STR) + 2,
oldString.indexOf(END_STR));
oldString = oldString.replace(START_STR + params + END_STR,
getParamsValue(params.trim(), map));
oldString = oldString.replace(START_STR + params + END_STR, eval(params, map)
.toString());
}
//如何是数值 类型,就按照数值类型进行设置
if (isNumber) {
@@ -288,11 +313,15 @@ public final class ExcelExportOfTemplateUtil extends ExcelExportBase {
}
}
//判断foreach 这种方法
if (oldString != null
&& (oldString.trim().startsWith("foreach||") || oldString.trim().startsWith(
"!foreach||"))) {
if (oldString != null && oldString.contains(FOREACH)) {
addListDataToExcel(cell, map, oldString.trim());
}
}
private boolean isNumber(String text) {
return text.startsWith(NUMBER_SYMBOL) || text.contains("{" + NUMBER_SYMBOL)
|| text.contains(" " + NUMBER_SYMBOL);
}
/**
@@ -304,10 +333,12 @@ public final class ExcelExportOfTemplateUtil extends ExcelExportBase {
*/
private void addListDataToExcel(Cell cell, Map<String, Object> map, String name)
throws Exception {
boolean isCreate = !name.startsWith("!");
Collection<?> datas = (Collection<?>) map.get(name.substring(name.indexOf("||") + 2,
name.indexOf(START_STR)));
List<String> columns = getAllDataColumns(cell, name);
boolean isCreate = !name.contains(FOREACH_NOT_CREATE);
name = name.replace(FOREACH_NOT_CREATE, EMPTY).replace(FOREACH, EMPTY)
.replace(START_STR, EMPTY);
String[] keys = name.replaceAll("\\s{1,}", " ").trim().split(" ");
Collection<?> datas = (Collection<?>) PoiPublicUtil.getParamsValue(keys[0], map);
List<String> columns = getAllDataColumns(cell, name.replace(keys[0], EMPTY));
if (datas == null) {
return;
}
@@ -317,7 +348,7 @@ public final class ExcelExportOfTemplateUtil extends ExcelExportBase {
//处理当前行
if (its.hasNext()) {
Object t = its.next();
setForEeachCellValue(isCreate, cell.getRow(), cell.getColumnIndex(), t, columns);
setForEeachCellValue(isCreate, cell.getRow(), cell.getColumnIndex(), t, columns, map);
}
while (its.hasNext()) {
Object t = its.next();
@@ -329,20 +360,32 @@ public final class ExcelExportOfTemplateUtil extends ExcelExportBase {
row = cell.getRow().getSheet().createRow(rowIndex - 1);
}
}
setForEeachCellValue(isCreate, row, cell.getColumnIndex(), t, columns);
setForEeachCellValue(isCreate, row, cell.getColumnIndex(), t, columns, map);
}
}
private void setForEeachCellValue(boolean isCreate, Row row, int columnIndex, Object t,
List<String> columns) throws Exception {
List<String> columns, Map<String, Object> map)
throws Exception {
for (int i = 0, max = columnIndex + columns.size(); i < max; i++) {
if (row.getCell(i) == null)
row.createCell(i);
}
for (int i = 0, max = columns.size(); i < max; i++) {
String val = String.valueOf(PoiPublicUtil.getValueDoWhile(t, columns.get(i)
.split("\\."), 0));
row.getCell(i + columnIndex).setCellValue(val);
boolean isNumber = false;
String tempStr = new String(columns.get(i));
if (isNumber(tempStr)) {
isNumber = true;
tempStr = tempStr.replace(NUMBER_SYMBOL, "");
}
map.put(teplateParams.getTempParams(), t);
String val = eval(tempStr, map).toString();
if (isNumber) {
row.getCell(i + columnIndex).setCellValue(Double.parseDouble(val));
row.getCell(i + columnIndex).setCellType(Cell.CELL_TYPE_NUMERIC);
} else {
row.getCell(i + columnIndex).setCellValue(val);
}
tempCreateCellSet.add(row.getRowNum() + "_" + (i + columnIndex));
}
@@ -357,20 +400,23 @@ public final class ExcelExportOfTemplateUtil extends ExcelExportBase {
private List<String> getAllDataColumns(Cell cell, String name) {
List<String> columns = new ArrayList<String>();
if (name.contains(END_STR)) {
columns.add(name.substring(name.indexOf(START_STR) + 2, name.indexOf(END_STR)).trim());
columns.add(name.replace(END_STR, EMPTY));
cell.setCellValue("");
return columns;
}
columns.add(name.substring(name.indexOf(START_STR) + 2).trim());
columns.add(name.trim());
int index = cell.getColumnIndex();
Cell tempCell;
while (true) {
tempCell = cell.getRow().getCell(++index);
if (tempCell == null) {
break;
}
String cellStringString;
try {//不允许为空
try {//允许为空,单表示已经完结了,因为可能被删除了
cellStringString = tempCell.getStringCellValue();
if (StringUtils.isBlank(cellStringString)) {
throw new ExcelExportException();
break;
}
} catch (Exception e) {
throw new ExcelExportException("for each 当中存在空字符串,请检查模板");
@@ -381,7 +427,12 @@ public final class ExcelExportOfTemplateUtil extends ExcelExportBase {
columns.add(cellStringString.trim().replace(END_STR, ""));
break;
} else {
columns.add(cellStringString.trim());
if (cellStringString.trim().contains(teplateParams.getTempParams())) {
columns.add(cellStringString.trim());
} else {
//最后一行被删除了
break;
}
}
}


+ 12
- 7
easypoi-base/src/main/java/org/jeecgframework/poi/util/PoiElUtil.java Zobrazit soubor

@@ -11,13 +11,18 @@ import org.jeecgframework.poi.exception.excel.ExcelExportException;
*/
public final class PoiElUtil {
private static final String LENGTH = "le:";
private static final String FORMAT_DATE = "fd:";
private static final String FORMAT_NUMBER = "fn:";
private static final String IF_DELETE = "!if:";
private static final String EMPTY = "";
private static final String LEFT_BRACKET = "(";
private static final String RIGHT_BRACKET = ")";
public static final String LENGTH = "le:";
public static final String FOREACH = "fe:";
public static final String FOREACH_NOT_CREATE = "!fe:";
public static final String START_STR = "{{";
public static final String END_STR = "}}";
public static final String NUMBER_SYMBOL = "n:";
public static final String FORMAT_DATE = "fd:";
public static final String FORMAT_NUMBER = "fn:";
public static final String IF_DELETE = "!if:";
public static final String EMPTY = "";
public static final String LEFT_BRACKET = "(";
public static final String RIGHT_BRACKET = ")";
private PoiElUtil() {
}


+ 8
- 3
easypoi-base/src/main/java/org/jeecgframework/poi/util/PoiPublicUtil.java Zobrazit soubor

@@ -37,6 +37,7 @@ import org.jeecgframework.poi.excel.entity.vo.PoiBaseConstants;
import org.jeecgframework.poi.word.entity.WordImageEntity;
import org.jeecgframework.poi.word.entity.params.ExcelListEntity;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTMarker;
/**
* EASYPOI 的公共基础类
* @author JueYue
@@ -362,12 +363,16 @@ public final class PoiPublicUtil {
* @param map
* @return
*/
public static Object getParamsValue(String params, Map<String, Object> map) throws Exception {
@SuppressWarnings("rawtypes")
public static Object getParamsValue(String params, Object object) throws Exception {
if (params.indexOf(".") != -1) {
String[] paramsArr = params.split("\\.");
return getValueDoWhile(map.get(paramsArr[0]), paramsArr, 1);
return getValueDoWhile(object, paramsArr, 0);
}
if (object instanceof Map) {
return ((Map) object).get(params);
}
return map.containsKey(params) ? map.get(params) : "";
return getMethod(params, object.getClass()).invoke(object, new Object[] {});
}
/**


+ 90
- 0
easypoi-base/src/main/java/org/jeecgframework/poi/util/PoiSheetUtility.java Zobrazit soubor

@@ -0,0 +1,90 @@
package org.jeecgframework.poi.util;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
/**
* 国外高手的,不过也不好,慎用,效率不行
* Helper functions to aid in the management of sheets
*/
public class PoiSheetUtility extends Object {
/**
* Given a sheet, this method deletes a column from a sheet and moves
* all the columns to the right of it to the left one cell.
*
* Note, this method will not update any formula references.
*
* @param sheet
* @param column
*/
public static void deleteColumn(Sheet sheet, int columnToDelete) {
int maxColumn = 0;
for (int r = 0; r < sheet.getLastRowNum() + 1; r++) {
Row row = sheet.getRow(r);
// if no row exists here; then nothing to do; next!
if (row == null)
continue;
// if the row doesn't have this many columns then we are good; next!
int lastColumn = row.getLastCellNum();
if (lastColumn > maxColumn)
maxColumn = lastColumn;
if (lastColumn < columnToDelete)
continue;
for (int x = columnToDelete + 1; x < lastColumn + 1; x++) {
Cell oldCell = row.getCell(x - 1);
if (oldCell != null)
row.removeCell(oldCell);
Cell nextCell = row.getCell(x);
if (nextCell != null) {
Cell newCell = row.createCell(x - 1, nextCell.getCellType());
cloneCell(newCell, nextCell);
}
}
}
// Adjust the column widths
for (int c = 0; c < maxColumn; c++) {
sheet.setColumnWidth(c, sheet.getColumnWidth(c + 1));
}
}
/*
* Takes an existing Cell and merges all the styles and forumla
* into the new one
*/
private static void cloneCell(Cell cNew, Cell cOld) {
cNew.setCellComment(cOld.getCellComment());
cNew.setCellStyle(cOld.getCellStyle());
switch (cNew.getCellType()) {
case Cell.CELL_TYPE_BOOLEAN: {
cNew.setCellValue(cOld.getBooleanCellValue());
break;
}
case Cell.CELL_TYPE_NUMERIC: {
cNew.setCellValue(cOld.getNumericCellValue());
break;
}
case Cell.CELL_TYPE_STRING: {
cNew.setCellValue(cOld.getStringCellValue());
break;
}
case Cell.CELL_TYPE_ERROR: {
cNew.setCellValue(cOld.getErrorCellValue());
break;
}
case Cell.CELL_TYPE_FORMULA: {
cNew.setCellFormula(cOld.getCellFormula());
break;
}
}
}
}

binární
easypoi-test/src/main/java/org/jeecgframework/poi/test/excel/doc/foreach.xlsx Zobrazit soubor


+ 4
- 0
easypoi-test/src/main/java/org/jeecgframework/poi/test/excel/template/TemplateForEachTest.java Zobrazit soubor

@@ -3,6 +3,7 @@ package org.jeecgframework.poi.test.excel.template;
import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -37,6 +38,9 @@ public class TemplateForEachTest {
list.add(entity);
}
map.put("entitylist", list);
map.put("letest", "12345678");
map.put("fntest", "12345678.2341234");
map.put("fdtest", new Date());
List<Map<String, Object>> mapList = new ArrayList<Map<String, Object>>();
for (int i = 0; i < 4; i++) {
Map<String, Object> testMap = new HashMap<String, Object>();


Načítá se…
Zrušit
Uložit