一.将表格拆分处理cn.afterturn easypoi-annotation 4.1.0 cn.afterturn easypoi-spring-boot-starter 4.1.0 org.apache.poi poi 4.1.2 org.apache.poi poi-ooxml 4.1.2
line3为第一部分
line5-9为第二部分
line12-15为第三部分
line16以后的为第四部分
使用ExcelimportUtil.importExcel()读取文件,由于一个inputstream无法重复读取,所以需要复制几份
private static ByteArrayOutputStream cloneInputStream(InputStream input) {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len;
while ((len = input.read(buffer)) > -1) {
baos.write(buffer, 0, len);
}
baos.flush();
return baos;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
三、获取列表数据复制流的方法来源于 https://blog.csdn.net/qq_25646191/article/details/78856639
//根据门店名字拆分获取多个列表 public static ListuploadSybReconciliation(InputStream excelInputStream) throws Exception { //默认跳过行数 int titleRows = 5; //门店名称默认起始行数 int shopNameIndex = 5; List list = Lists.newArrayList(); ByteArrayOutputStream bao = cloneInputStream(excelInputStream); XSSFWorkbook workbook = new XSSFWorkbook(new ByteArrayInputStream(bao.toByteArray())); XSSFSheet sheet = workbook.getSheetAt(0); for (int i = 0; i < sheet.getLastRowNum(); i++) { XSSFRow row = sheet.getRow(i); XSSFCell cell = row.getCell(0); String value = cell.getStringCellValue(); if(StringUtil.isNotEmpty(value) && "门店名称".equals(value)){ shopNameIndex = row.getRowNum(); log.info("门店名称在{}行",shopNameIndex); continue; } if(StringUtil.isNotEmpty(value) && "交易对账明细".equals(value)){ titleRows = row.getRowNum()+1; log.info("交易对账明细在第{}行",titleRows); break; } //获取所有门店名字 if(i > shopNameIndex && StringUtil.isNotEmpty(value)){ ExcelIndex index = new ExcelIndex(); index.setShopName(value); list.add(index); continue; } } //获取门店名所在的row 开始和结束index int now = 0; for (int i = titleRows; i < sheet.getLastRowNum(); i++) { XSSFRow row = sheet.getRow(i); String value1 = row.getCell(0).getStringCellValue(); String value2 = row.getCell(1).getStringCellValue(); for (int j = 0; j < list.size(); j++) { if(StringUtil.isNotEmpty(value1) && list.get(j).getShopName().equals(value1)){ list.get(j).setStartIndex(row.getRowNum()); now = j; continue; } if(StringUtil.isNotEmpty(value2) && value2.equals("小计")){ list.get(now).setEndIndex(row.getRowNum()); i = row.getRowNum()+1; break; } } } //获取每个门店的明细列表 List sybReconciliationResults = Lists.newArrayList(); list.forEach(index -> { if(index.getStartIndex() == null || index.getEndIndex() == null){ return; } //3.交易对账明细 importParams params3 = new importParams(); params3.setTitleRows(index.getStartIndex()+1); params3.setHeadRows(1); params3.setLastOfInvalidRow(sheet.getLastRowNum() - index.getEndIndex() + 1); params3.setKeyMark(":"); params3.setReadSingleCell(true); try { SybReconciliationResult sybReconciliationResult = new SybReconciliationResult(); sybReconciliationResult.setShopName(index.getShopName()); List data = new ExcelimportServiceImpl().importExcelByIs(new ByteArrayInputStream(bao.toByteArray()), SybReconciliationDetail.class, params3,false).getList(); sybReconciliationResult.setSybReconciliationDetailList(data); sybReconciliationResults.add(sybReconciliationResult); } catch (Exception e) { e.printStackTrace(); } }); List payPlatformBillDTOList = sybReconciliationResults.stream().map(it -> { List payPlatformBillDTOS = new BeanConverterUtils<>(SybReconciliationDetail.class, PayPlatformBillDTO.class).doForwardList(it.getSybReconciliationDetailList()); payPlatformBillDTOS.forEach(dto -> dto.setMerchantName(it.getShopName())); return payPlatformBillDTOS; }).flatMap(Collection::stream).collect(Collectors.toList()); return payPlatformBillDTOList; }
四、获取合并单元格poi原始api文档http://doc.wupaas.com/docs/easypoi/easypoi-1c0u4mo8p4ro8
终端号字段的单元格是合并过后的单元格,第二行开始获取cell为null,需要重写easypoi中ExcelimportService的importExcelByIs
import cn.afterturn.easypoi.excel.annotation.ExcelTarget;
import cn.afterturn.easypoi.excel.entity.importParams;
import cn.afterturn.easypoi.excel.entity.params.ExcelCollectionParams;
import cn.afterturn.easypoi.excel.entity.params.ExcelimportEntity;
import cn.afterturn.easypoi.excel.entity.result.ExcelimportResult;
import cn.afterturn.easypoi.excel.entity.vo.baseEntityTypeConstants;
import cn.afterturn.easypoi.excel.imports.CellValueService;
import cn.afterturn.easypoi.excel.imports.ExcelimportService;
import cn.afterturn.easypoi.excel.imports.recursive.ExcelimportForkJoinWork;
import cn.afterturn.easypoi.exception.excel.ExcelimportException;
import cn.afterturn.easypoi.exception.excel.enums.ExcelimportEnum;
import cn.afterturn.easypoi.handler.inter.IExcelDataModel;
import cn.afterturn.easypoi.util.PoiCellUtil;
import cn.afterturn.easypoi.util.PoiPublicUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.formula.functions.T;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.util.IOUtils;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.*;
import java.lang.reflect.Field;
import java.util.*;
import java.util.concurrent.ForkJoinPool;
@Slf4j
public class ExcelimportServiceImpl extends ExcelimportService {
private CellValueService cellValueServer;
private boolean verifyFail = false;
private CellStyle errorCellStyle;
private List successRow;
private List failRow;
private List failCollection;
public ExcelimportServiceImpl() {
successRow = new ArrayList();
failRow = new ArrayList();
failCollection = new ArrayList();
this.cellValueServer = new CellValueService();
}
private String getKeyValue(Cell cell) {
Object obj = PoiCellUtil.getCellValue(cell);
return obj == null ? null : obj.toString().trim();
}
private String getSaveUrl(ExcelimportEntity excelimportEntity, Object object) throws Exception {
String url = "";
if (ExcelimportEntity.IMG_SAVE_PATH.equals(excelimportEntity.getSaveUrl())) {
if (excelimportEntity.getMethods() != null
&& excelimportEntity.getMethods().size() > 0) {
object = getFieldBySomeMethod(excelimportEntity.getMethods(), object);
}
url = object.getClass().getName()
.split("\.")[object.getClass().getName().split("\.").length - 1];
return excelimportEntity.getSaveUrl() + File.separator + url;
}
return excelimportEntity.getSaveUrl();
}
private List importExcel(Collection result, Sheet sheet, Class> pojoClass,
importParams params,
Map pictures) throws Exception {
List collection = new ArrayList();
Map excelParams = new HashMap();
List excelCollection = new ArrayList();
String targetId = null;
i18nHandler = params.getI18nHandler();
boolean isMap = Map.class.equals(pojoClass);
if (!isMap) {
Field[] fileds = PoiPublicUtil.getClassFields(pojoClass);
ExcelTarget etarget = pojoClass.getAnnotation(ExcelTarget.class);
if (etarget != null) {
targetId = etarget.value();
}
getAllExcelField(targetId, fileds, excelParams, excelCollection, pojoClass, null, null);
}
Iterator rows = sheet.rowIterator();
for (int j = 0; j < params.getTitleRows(); j++) {
rows.next();
}
Map titlemap = getTitleMap(rows, params, excelCollection, excelParams);
checkIsValidTemplate(titlemap, excelParams, params, excelCollection);
Row row = null;
Object object = null;
String picId;
int readRow = 1;
//跳过无效行
for (int i = 0; i < params.getStartRows(); i++) {
rows.next();
}
//判断index 和集合,集合情况默认为第一列
if (excelCollection.size() > 0 && params.getKeyIndex() == null) {
params.setKeyIndex(0);
}
if (params.isConcurrentTask()) {
ForkJoinPool forkJoinPool = new ForkJoinPool();
int endRow = sheet.getLastRowNum() - params.getLastOfInvalidRow();
if (params.getReadRows() > 0) {
endRow = params.getReadRows();
}
ExcelimportForkJoinWork task = new ExcelimportForkJoinWork(params.getStartRows() + params.getHeadRows() + params.getTitleRows(), endRow, sheet, params, pojoClass, this, targetId, titlemap, excelParams);
ExcelimportResult forkJoinResult = forkJoinPool.invoke(task);
collection = forkJoinResult.getList();
failCollection = forkJoinResult.getFailList();
} else {
StringBuilder errorMsg;
while (rows.hasNext()
&& (row == null
|| sheet.getLastRowNum() - row.getRowNum() > params.getLastOfInvalidRow())) {
if (params.getReadRows() > 0 && readRow > params.getReadRows()) {
break;
}
row = rows.next();
// Fix 如果row为无效行时候跳出
if (sheet.getLastRowNum() - row.getRowNum() < params.getLastOfInvalidRow()) {
break;
}
if (row.getLastCellNum() < 0) {
continue;
}
if (isMap && object != null) {
((Map) object).put("excelRowNum", row.getRowNum());
}
errorMsg = new StringBuilder();
// 判断是集合元素还是不是集合元素,如果是就继续加入这个集合,不是就创建新的对象
// keyIndex 如果为空就不处理,仍然处理这一行
if (params.getKeyIndex() != null
&& (row.getCell(params.getKeyIndex()) == null
|| StringUtils.isEmpty(getKeyValue(row.getCell(params.getKeyIndex()))))
&& object != null) {
for (ExcelCollectionParams param : excelCollection) {
addListContinue(object, param, row, titlemap, targetId, pictures, params, errorMsg);
}
} else {
object = PoiPublicUtil.createObject(pojoClass, targetId);
try {
Set keys = titlemap.keySet();
for (Integer cn : keys) {
Cell cell = row.getCell(cn);
String titleString = (String) titlemap.get(cn);
if (excelParams.containsKey(titleString) || isMap) {
if (excelParams.get(titleString) != null
&& excelParams.get(titleString).getType() == baseEntityTypeConstants.IMAGE_TYPE) {
picId = row.getRowNum() + "_" + cn;
saveImage(object, picId, excelParams, titleString, pictures,
params);
} else {
try {
saveFieldValue(sheet,params, object, cell, excelParams, titleString, row);
} catch (ExcelimportException e) {
// 如果需要去校验就忽略,这个错误,继续执行
if (params.isNeedVerify() && ExcelimportEnum.GET_VALUE_ERROR.equals(e.getType())) {
errorMsg.append(" ").append(titleString).append(ExcelimportEnum.GET_VALUE_ERROR.getMsg());
}
}
}
}
}
//for (int i = row.getFirstCellNum(), le = titlemap.size(); i < le; i++) {
//}
if (object instanceof IExcelDataModel) {
((IExcelDataModel) object).setRowNum(row.getRowNum());
}
for (ExcelCollectionParams param : excelCollection) {
addListContinue(object, param, row, titlemap, targetId, pictures, params, errorMsg);
}
if (verifyingDataValidity(object, row, params, isMap, errorMsg)) {
collection.add(object);
} else {
failCollection.add(object);
}
} catch (ExcelimportException e) {
log.error("excel import error , row num:{},obj:{}", readRow, ReflectionToStringBuilder.toString(object));
if (!e.getType().equals(ExcelimportEnum.VERIFY_ERROR)) {
throw new ExcelimportException(e.getType(), e);
}
} catch (Exception e) {
log.error("excel import error , row num:{},obj:{}", readRow, ReflectionToStringBuilder.toString(object));
throw new RuntimeException(e);
}
}
readRow++;
}
}
return collection;
}
public boolean 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 true;
}
}
}
return false;
}
public String getMergedRegionValue(Sheet sheet, int row, int column) {
int sheetMergeCount = sheet.getNumMergedRegions();
for (int i = 0; i < sheetMergeCount; i++) {
CellRangeAddress ca = sheet.getMergedRegion(i);
int firstColumn = ca.getFirstColumn();
int lastColumn = ca.getLastColumn();
int firstRow = ca.getFirstRow();
int lastRow = ca.getLastRow();
if (row >= firstRow && row <= lastRow) {
if (column >= firstColumn && column <= lastColumn) {
Row fRow = sheet.getRow(firstRow);
Cell fCell = fRow.getCell(firstColumn);
return getCellValue(fCell);
}
}
}
return null;
}
public String getCellValue(Cell cell) {
if (cell == null) return "";
if (cell.getCellType() == CellType.STRING) {
return cell.getStringCellValue();
} else if (cell.getCellType() == CellType.BOOLEAN) {
return String.valueOf(cell.getBooleanCellValue());
} else if (cell.getCellType() == CellType.FORMULA) {
return cell.getCellFormula();
} else if (cell.getCellType() == CellType.NUMERIC) {
return String.valueOf(cell.getNumericCellValue());
}
return "";
}
private Map getTitleMap(Iterator rows, importParams params,
List excelCollection,
Map excelParams) {
Map titlemap = new linkedHashMap();
Iterator cellTitle;
String collectionName = null;
ExcelCollectionParams collectionParams = null;
Row row = null;
for (int j = 0; j < params.getHeadRows(); j++) {
row = rows.next();
if (row == null) {
continue;
}
cellTitle = row.cellIterator();
while (cellTitle.hasNext()) {
Cell cell = cellTitle.next();
String value = getKeyValue(cell);
value = value.replace("n", "");
int i = cell.getColumnIndex();
//用以支持重名导入
if (StringUtils.isNotEmpty(value)) {
if (titlemap.containsKey(i)) {
collectionName = titlemap.get(i);
collectionParams = getCollectionParams(excelCollection, collectionName);
titlemap.put(i, collectionName + "_" + value);
} else if (StringUtils.isNotEmpty(collectionName) && collectionParams != null
&& collectionParams.getExcelParams()
.containsKey(collectionName + "_" + value)) {
titlemap.put(i, collectionName + "_" + value);
} else {
collectionName = null;
collectionParams = null;
}
if (StringUtils.isEmpty(collectionName)) {
titlemap.put(i, value);
}
}
}
}
// 处理指定列的情况
Set keys = excelParams.keySet();
for (String key : keys) {
if (key.startsWith("FIXED_")) {
String[] arr = key.split("_");
titlemap.put(Integer.parseInt(arr[1]), key);
}
}
return titlemap;
}
private ExcelCollectionParams getCollectionParams(List excelCollection,
String collectionName) {
for (ExcelCollectionParams excelCollectionParams : excelCollection) {
if (collectionName.equals(excelCollectionParams.getExcelName())) {
return excelCollectionParams;
}
}
return null;
}
@Override
public ExcelimportResult importExcelByIs(InputStream inputstream, Class> pojoClass,
importParams params, boolean needMore) throws Exception {
if (log.isDebugEnabled()) {
log.debug("Excel import start ,class is {}", pojoClass);
}
List result = new ArrayList();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ExcelimportResult importResult;
try {
byte[] buffer = new byte[1024];
int len;
while ((len = inputstream.read(buffer)) > -1) {
baos.write(buffer, 0, len);
}
baos.flush();
InputStream userIs = new ByteArrayInputStream(baos.toByteArray());
if (log.isDebugEnabled()) {
log.debug("Excel clone success");
}
Workbook book = WorkbookFactory.create(userIs);
boolean isXSSFWorkbook = !(book instanceof HSSFWorkbook);
if (log.isDebugEnabled()) {
log.debug("Workbook create success");
}
importResult = new ExcelimportResult();
createErrorCellStyle(book);
Map pictures;
for (int i = params.getStartSheetIndex(); i < params.getStartSheetIndex()
+ params.getSheetNum(); i++) {
if (log.isDebugEnabled()) {
log.debug(" start to read excel by is ,startTime is {}", new Date());
}
if (isXSSFWorkbook) {
pictures = PoiPublicUtil.getSheetPictrues07((XSSFSheet) book.getSheetAt(i),
(XSSFWorkbook) book);
} else {
pictures = PoiPublicUtil.getSheetPictrues03((HSSFSheet) book.getSheetAt(i),
(HSSFWorkbook) book);
}
if (log.isDebugEnabled()) {
log.debug(" end to read excel by is ,endTime is {}", new Date());
}
result.addAll(importExcel(result, book.getSheetAt(i), pojoClass, params, pictures));
if (log.isDebugEnabled()) {
log.debug(" end to read excel list by sheet ,endTime is {}", new Date());
}
if (params.isReadSingleCell()) {
readSingleCell(importResult, book.getSheetAt(i), params);
if (log.isDebugEnabled()) {
log.debug(" read Key-Value ,endTime is {}", System.currentTimeMillis());
}
}
}
if (params.isNeedSave()) {
saveThisExcel(params, pojoClass, isXSSFWorkbook, book);
}
importResult.setList(result);
if (needMore) {
InputStream successIs = new ByteArrayInputStream(baos.toByteArray());
try {
Workbook successBook = WorkbookFactory.create(successIs);
importResult.setWorkbook(removeSuperfluousRows(successBook, failRow, params));
importResult.setFailWorkbook(removeSuperfluousRows(book, successRow, params));
importResult.setFailList(failCollection);
importResult.setVerfiyFail(verifyFail);
} finally {
successIs.close();
}
}
} finally {
IOUtils.closeQuietly(baos);
}
return importResult;
}
private Workbook removeSuperfluousRows(Workbook book, List rowList, importParams params) {
for (int i = params.getStartSheetIndex(); i < params.getStartSheetIndex()
+ params.getSheetNum(); i++) {
for (int j = rowList.size() - 1; j >= 0; j--) {
if (rowList.get(j).getRowNum() < rowList.get(j).getSheet().getLastRowNum()) {
book.getSheetAt(i).shiftRows(rowList.get(j).getRowNum() + 1, rowList.get(j).getSheet().getLastRowNum(), -1);
} else if (rowList.get(j).getRowNum() == rowList.get(j).getSheet().getLastRowNum()) {
book.getSheetAt(i).createRow(rowList.get(j).getRowNum() + 1);
book.getSheetAt(i).shiftRows(rowList.get(j).getRowNum() + 1, rowList.get(j).getSheet().getLastRowNum() + 1, -1);
}
}
}
return book;
}
private void readSingleCell(ExcelimportResult result, Sheet sheet, importParams params) {
if (result.getMap() == null) {
result.setMap(new HashMap());
}
for (int i = 0; i < params.getTitleRows() + params.getHeadRows() + params.getStartRows(); i++) {
getSingleCellValueForRow(result, sheet.getRow(i), params);
}
for (int i = sheet.getLastRowNum() - params.getLastOfInvalidRow(); i < sheet.getLastRowNum(); i++) {
getSingleCellValueForRow(result, sheet.getRow(i), params);
}
}
private void getSingleCellValueForRow(ExcelimportResult result, Row row, importParams params) {
for (int j = row.getFirstCellNum(), le = row.getLastCellNum(); j < le; j++) {
String text = PoiCellUtil.getCellValue(row.getCell(j));
if (StringUtils.isNoneBlank(text) && text.endsWith(params.getKeyMark())) {
if (result.getMap().containsKey(text)) {
if (result.getMap().get(text) instanceof String) {
List list = new ArrayList();
list.add((String) result.getMap().get(text));
result.getMap().put(text, list);
}
((List) result.getMap().get(text)).add(PoiCellUtil.getCellValue(row.getCell(++j)));
} else {
result.getMap().put(text, PoiCellUtil.getCellValue(row.getCell(++j)));
}
}
}
}
private void checkIsValidTemplate(Map titlemap,
Map excelParams,
importParams params,
List excelCollection) {
if (params.getimportFields() != null) {
if (params.isNeedCheckOrder()) { // 同时校验列顺序
if (params.getimportFields().length != titlemap.size()) {
log.error("excel列顺序不一致");
throw new ExcelimportException(ExcelimportEnum.IS_NOT_A_VALID_TEMPLATE);
}
int i = 0;
for (String title : titlemap.values()) {
if (!StringUtils.equals(title, params.getimportFields()[i++])) {
log.error("excel列顺序不一致");
throw new ExcelimportException(ExcelimportEnum.IS_NOT_A_VALID_TEMPLATE);
}
}
} else {
for (int i = 0, le = params.getimportFields().length; i < le; i++) {
if (!titlemap.containsValue(params.getimportFields()[i])) {
throw new ExcelimportException(ExcelimportEnum.IS_NOT_A_VALID_TEMPLATE);
}
}
}
} else {
Collection collection = excelParams.values();
for (ExcelimportEntity excelimportEntity : collection) {
if (excelimportEntity.isimportField()
&& !titlemap.containsValue(excelimportEntity.getName())) {
log.error(excelimportEntity.getName() + "必须有,但是没找到");
throw new ExcelimportException(ExcelimportEnum.IS_NOT_A_VALID_TEMPLATE);
}
}
for (int i = 0, le = excelCollection.size(); i < le; i++) {
ExcelCollectionParams collectionparams = excelCollection.get(i);
collection = collectionparams.getExcelParams().values();
for (ExcelimportEntity excelimportEntity : collection) {
if (excelimportEntity.isimportField() && !titlemap.containsValue(
collectionparams.getExcelName() + "_" + excelimportEntity.getName())) {
throw new ExcelimportException(ExcelimportEnum.IS_NOT_A_VALID_TEMPLATE);
}
}
}
}
}
public void saveFieldValue(Sheet sheet,importParams params, Object object, Cell cell,
Map excelParams, String titleString,
Row row) throws Exception {
String chopper = "";
Object value = cellValueServer.getValue(params.getDataHandler(), object, cell, excelParams,
titleString, params.getDictHandler());
//判断是否是合并单元格
if(isMergedRegion(sheet,row.getRowNum(),cell.getColumnIndex())){
chopper = getMergedRegionValue(sheet,row.getRowNum(),cell.getColumnIndex());
log.info("合并列:{}",chopper);
value = chopper;
}
if (object instanceof Map) {
if (params.getDataHandler() != null) {
params.getDataHandler().setMapValue((Map) object, titleString, value);
} else {
((Map) object).put(titleString, value);
}
} else {
setValues(excelParams.get(titleString), object, value);
}
}
private void saveImage(Object object, String picId, Map excelParams,
String titleString, Map pictures,
importParams params) throws Exception {
if (pictures == null) {
return;
}
PictureData image = pictures.get(picId);
if (image == null) {
return;
}
byte[] data = image.getData();
String fileName = "pic" + Math.round(Math.random() * 100000000000L);
fileName += "." + PoiPublicUtil.getFileExtendName(data);
if (excelParams.get(titleString).getSaveType() == 1) {
String path = getSaveUrl(excelParams.get(titleString), object);
File savefile = new File(path);
if (!savefile.exists()) {
savefile.mkdirs();
}
savefile = new File(path + File.separator + fileName);
FileOutputStream fos = new FileOutputStream(savefile);
try {
fos.write(data);
} finally {
IOUtils.closeQuietly(fos);
}
setValues(excelParams.get(titleString), object,
getSaveUrl(excelParams.get(titleString), object) + File.separator + fileName);
} else {
setValues(excelParams.get(titleString), object, data);
}
}
private void createErrorCellStyle(Workbook workbook) {
errorCellStyle = workbook.createCellStyle();
Font font = workbook.createFont();
font.setColor(Font.COLOR_RED);
errorCellStyle.setFont(font);
}
}
|
判断合并单元格isMergedRegion() 并获取合并单元格值getMergedRegionValue() https://blog.csdn.net/ycb1689/article/details/9764191
打印结果
map = SybReconciliationDetail(terminalNo=00000001, dealTime=11:07:12, dealType=消费, voucherNo=000545, cardNo=625802****3406, cardType=信用卡, cardBankName=招商银行信用卡中心, dealAmount=50.00, serviceCharge=0.25, dealDate=2016-04-14, serialNo=17269813, orderNo=null, remark=null) map = SybReconciliationDetail(terminalNo=00000001, dealTime=13:08:29, dealType=消费, voucherNo=000555, cardNo=625802****3406, cardType=信用卡, cardBankName=招商银行信用卡中心, dealAmount=50.00, serviceCharge=0.25, dealDate=2016-04-14, serialNo=17269825, orderNo=null, remark=null) map = SybReconciliationDetail(terminalNo=00000001, dealTime=13:16:06, dealType=消费, voucherNo=000557, cardNo=621700****5226, cardType=借记卡, cardBankName=中国建设银行, dealAmount=50.00, serviceCharge=0.25, dealDate=2016-04-14, serialNo=17269826, orderNo=null, remark=null)
————————————————————————————————————————————————————
TODO 如何忽略excel上面公章水印


