| @@ -7,7 +7,7 @@ import com.google.common.cache.CacheLoader; | |||
| import com.google.common.cache.LoadingCache; | |||
| import cn.afterturn.easypoi.excel.entity.ExcelToHtmlParams; | |||
| import cn.afterturn.easypoi.excel.html.ExcelToHtmlServer; | |||
| import cn.afterturn.easypoi.excel.html.ExcelToHtmlService; | |||
| /** | |||
| * Excel 转变成为Html 的缓存 | |||
| @@ -23,7 +23,7 @@ public class HtmlCache { | |||
| .build(new CacheLoader<ExcelToHtmlParams, String>() { | |||
| @Override | |||
| public String load(ExcelToHtmlParams params) throws Exception { | |||
| return new ExcelToHtmlServer(params).printPage(); | |||
| return new ExcelToHtmlService(params).printPage(); | |||
| } | |||
| }); | |||
| } | |||
| @@ -49,7 +49,7 @@ public class FileLoaderImpl implements IFileLoader { | |||
| //获取项目文件 | |||
| fileis = ClassLoader.getSystemResourceAsStream(url); | |||
| if (fileis == null) { | |||
| //最后再拿想对文件路径 | |||
| //最后再拿相对文件路径 | |||
| String path = PoiPublicUtil.getWebRootPath(url); | |||
| fileis = new FileInputStream(path); | |||
| } | |||
| @@ -62,8 +62,6 @@ public class FileLoaderImpl implements IFileLoader { | |||
| } | |||
| baos.flush(); | |||
| return baos.toByteArray(); | |||
| } catch (FileNotFoundException e) { | |||
| LOGGER.error(e.getMessage(), e); | |||
| } catch (IOException e) { | |||
| LOGGER.error(e.getMessage(), e); | |||
| } finally { | |||
| @@ -28,8 +28,8 @@ import cn.afterturn.easypoi.excel.entity.ExportParams; | |||
| import cn.afterturn.easypoi.excel.entity.TemplateExportParams; | |||
| import cn.afterturn.easypoi.excel.entity.enmus.ExcelType; | |||
| import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity; | |||
| import cn.afterturn.easypoi.excel.export.ExcelBatchExportServer; | |||
| import cn.afterturn.easypoi.excel.export.ExcelExportServer; | |||
| import cn.afterturn.easypoi.excel.export.ExcelBatchExportService; | |||
| import cn.afterturn.easypoi.excel.export.ExcelExportService; | |||
| import cn.afterturn.easypoi.excel.export.template.ExcelExportOfTemplateUtil; | |||
| /** | |||
| @@ -54,15 +54,15 @@ public class ExcelExportUtil { | |||
| */ | |||
| public static Workbook exportBigExcel(ExportParams entity, Class<?> pojoClass, | |||
| Collection<?> dataSet) { | |||
| ExcelBatchExportServer batachServer = ExcelBatchExportServer | |||
| .getExcelBatchExportServer(entity, pojoClass); | |||
| return batachServer.appendData(dataSet); | |||
| ExcelBatchExportService batchService = ExcelBatchExportService | |||
| .getExcelBatchExportService(entity, pojoClass); | |||
| return batchService.appendData(dataSet); | |||
| } | |||
| public static void closeExportBigExcel() { | |||
| ExcelBatchExportServer batachServer = ExcelBatchExportServer.getExcelBatchExportServer(null, | |||
| ExcelBatchExportService batchService = ExcelBatchExportService.getExcelBatchExportService(null, | |||
| null); | |||
| batachServer.closeExportBigExcel(); | |||
| batchService.closeExportBigExcel(); | |||
| } | |||
| /** | |||
| @@ -76,7 +76,7 @@ public class ExcelExportUtil { | |||
| public static Workbook exportExcel(ExportParams entity, Class<?> pojoClass, | |||
| Collection<?> dataSet) { | |||
| Workbook workbook = getWorkbook(entity.getType(),dataSet.size()); | |||
| new ExcelExportServer().createSheet(workbook, entity, pojoClass, dataSet); | |||
| new ExcelExportService().createSheet(workbook, entity, pojoClass, dataSet); | |||
| return workbook; | |||
| } | |||
| @@ -102,7 +102,7 @@ public class ExcelExportUtil { | |||
| public static Workbook exportExcel(ExportParams entity, List<ExcelExportEntity> entityList, | |||
| Collection<? extends Map<?, ?>> dataSet) { | |||
| Workbook workbook = getWorkbook(entity.getType(),dataSet.size());; | |||
| new ExcelExportServer().createSheetForMap(workbook, entity, entityList, dataSet); | |||
| new ExcelExportService().createSheetForMap(workbook, entity, entityList, dataSet); | |||
| return workbook; | |||
| } | |||
| @@ -117,8 +117,8 @@ public class ExcelExportUtil { | |||
| public static Workbook exportExcel(List<Map<String, Object>> list, ExcelType type) { | |||
| Workbook workbook = getWorkbook(type,0); | |||
| for (Map<String, Object> map : list) { | |||
| ExcelExportServer server = new ExcelExportServer(); | |||
| server.createSheet(workbook, (ExportParams) map.get("title"), | |||
| ExcelExportService service = new ExcelExportService(); | |||
| service.createSheet(workbook, (ExportParams) map.get("title"), | |||
| (Class<?>) map.get("entity"), (Collection<?>) map.get("data")); | |||
| } | |||
| return workbook; | |||
| @@ -26,7 +26,7 @@ import org.slf4j.LoggerFactory; | |||
| import cn.afterturn.easypoi.excel.entity.ImportParams; | |||
| import cn.afterturn.easypoi.excel.entity.result.ExcelImportResult; | |||
| import cn.afterturn.easypoi.excel.imports.ExcelImportServer; | |||
| import cn.afterturn.easypoi.excel.imports.ExcelImportService; | |||
| import cn.afterturn.easypoi.excel.imports.sax.SaxReadExcel; | |||
| import cn.afterturn.easypoi.excel.imports.sax.parse.ISaxRowRead; | |||
| import cn.afterturn.easypoi.exception.excel.ExcelImportException; | |||
| @@ -59,7 +59,7 @@ public class ExcelImportUtil { | |||
| FileInputStream in = null; | |||
| try { | |||
| in = new FileInputStream(file); | |||
| return new ExcelImportServer().importExcelByIs(in, pojoClass, params).getList(); | |||
| return new ExcelImportService().importExcelByIs(in, pojoClass, params).getList(); | |||
| } catch (ExcelImportException e) { | |||
| throw new ExcelImportException(e.getType(), e); | |||
| } catch (Exception e) { | |||
| @@ -81,7 +81,7 @@ public class ExcelImportUtil { | |||
| */ | |||
| public static <T> List<T> importExcel(InputStream inputstream, Class<?> pojoClass, | |||
| ImportParams params) throws Exception { | |||
| return new ExcelImportServer().importExcelByIs(inputstream, pojoClass, params).getList(); | |||
| return new ExcelImportService().importExcelByIs(inputstream, pojoClass, params).getList(); | |||
| } | |||
| /** | |||
| @@ -97,7 +97,7 @@ public class ExcelImportUtil { | |||
| public static <T> ExcelImportResult<T> importExcelMore(InputStream inputstream, | |||
| Class<?> pojoClass, | |||
| ImportParams params) throws Exception { | |||
| return new ExcelImportServer().importExcelByIs(inputstream, pojoClass, params); | |||
| return new ExcelImportService().importExcelByIs(inputstream, pojoClass, params); | |||
| } | |||
| /** | |||
| @@ -113,7 +113,7 @@ public class ExcelImportUtil { | |||
| FileInputStream in = null; | |||
| try { | |||
| in = new FileInputStream(file); | |||
| return new ExcelImportServer().importExcelByIs(in, pojoClass, params); | |||
| return new ExcelImportService().importExcelByIs(in, pojoClass, params); | |||
| } catch (ExcelImportException e) { | |||
| throw new ExcelImportException(e.getType(), e); | |||
| } catch (Exception e) { | |||
| @@ -11,7 +11,7 @@ import java.io.InputStream; | |||
| import cn.afterturn.easypoi.cache.HtmlCache; | |||
| import cn.afterturn.easypoi.excel.entity.ExcelToHtmlParams; | |||
| import cn.afterturn.easypoi.excel.entity.enmus.ExcelType; | |||
| import cn.afterturn.easypoi.excel.html.HtmlToExcelServer; | |||
| import cn.afterturn.easypoi.excel.html.HtmlToExcelService; | |||
| import cn.afterturn.easypoi.exception.excel.ExcelExportException; | |||
| import cn.afterturn.easypoi.exception.excel.enums.ExcelExportEnum; | |||
| @@ -65,7 +65,7 @@ public class ExcelXorHtmlUtil { | |||
| } else { | |||
| workbook = new XSSFWorkbook(); | |||
| } | |||
| new HtmlToExcelServer().createSheet(html, workbook); | |||
| new HtmlToExcelService().createSheet(html, workbook); | |||
| return workbook; | |||
| } | |||
| @@ -1,159 +1,159 @@ | |||
| package cn.afterturn.easypoi.excel.export; | |||
| import java.lang.reflect.Field; | |||
| import java.util.ArrayList; | |||
| import java.util.Arrays; | |||
| import java.util.Collection; | |||
| import java.util.Iterator; | |||
| import java.util.List; | |||
| import org.apache.poi.ss.usermodel.Drawing; | |||
| import org.apache.poi.ss.usermodel.Sheet; | |||
| import org.apache.poi.ss.usermodel.Workbook; | |||
| import org.apache.poi.xssf.streaming.SXSSFWorkbook; | |||
| import cn.afterturn.easypoi.excel.annotation.ExcelTarget; | |||
| import cn.afterturn.easypoi.excel.entity.ExportParams; | |||
| import cn.afterturn.easypoi.excel.entity.enmus.ExcelType; | |||
| import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity; | |||
| import cn.afterturn.easypoi.excel.export.styler.IExcelExportStyler; | |||
| import cn.afterturn.easypoi.exception.excel.ExcelExportException; | |||
| import cn.afterturn.easypoi.exception.excel.enums.ExcelExportEnum; | |||
| import cn.afterturn.easypoi.util.PoiExcelGraphDataUtil; | |||
| import cn.afterturn.easypoi.util.PoiPublicUtil; | |||
| /** | |||
| * 提供批次插入服务 | |||
| * @author JueYue | |||
| * 2016年8月29日 | |||
| */ | |||
| public class ExcelBatchExportServer extends ExcelExportServer { | |||
| private static ThreadLocal<ExcelBatchExportServer> THREAD_LOCAL = new ThreadLocal<ExcelBatchExportServer>(); | |||
| private Workbook workbook; | |||
| private Sheet sheet; | |||
| private List<ExcelExportEntity> excelParams; | |||
| private ExportParams entity; | |||
| private int titleHeight; | |||
| private Drawing patriarch; | |||
| private short rowHeight; | |||
| private int index; | |||
| public void init(ExportParams entity, Class<?> pojoClass) { | |||
| LOGGER.debug("ExcelBatchExportServer only support SXSSFWorkbook"); | |||
| entity.setType(ExcelType.XSSF); | |||
| workbook = new SXSSFWorkbook(); | |||
| this.entity = entity; | |||
| super.type = entity.getType(); | |||
| createSheet(workbook, entity, pojoClass); | |||
| if (entity.getMaxNum() == 0) { | |||
| entity.setMaxNum(1000000); | |||
| } | |||
| insertDataToSheet(workbook, entity, excelParams, null, sheet); | |||
| } | |||
| public void createSheet(Workbook workbook, ExportParams entity, Class<?> pojoClass) { | |||
| if (LOGGER.isDebugEnabled()) { | |||
| LOGGER.debug("Excel export start ,class is {}", pojoClass); | |||
| LOGGER.debug("Excel version is {}", | |||
| entity.getType().equals(ExcelType.HSSF) ? "03" : "07"); | |||
| } | |||
| if (workbook == null || entity == null || pojoClass == null) { | |||
| throw new ExcelExportException(ExcelExportEnum.PARAMETER_ERROR); | |||
| } | |||
| try { | |||
| excelParams = new ArrayList<ExcelExportEntity>(); | |||
| if (entity.isAddIndex()) { | |||
| excelParams.add(indexExcelEntity(entity)); | |||
| } | |||
| // 得到所有字段 | |||
| Field[] fileds = PoiPublicUtil.getClassFields(pojoClass); | |||
| ExcelTarget etarget = pojoClass.getAnnotation(ExcelTarget.class); | |||
| String targetId = etarget == null ? null : etarget.value(); | |||
| getAllExcelField(entity.getExclusions(), targetId, fileds, excelParams, pojoClass, | |||
| null, null); | |||
| sortAllParams(excelParams); | |||
| try { | |||
| sheet = workbook.createSheet(entity.getSheetName()); | |||
| } catch (Exception e) { | |||
| // 重复遍历,出现了重名现象,创建非指定的名称Sheet | |||
| sheet = workbook.createSheet(); | |||
| } | |||
| } catch (Exception e) { | |||
| throw new ExcelExportException(ExcelExportEnum.EXPORT_ERROR, e); | |||
| } | |||
| } | |||
| public Workbook appendData(Collection<?> dataSet) { | |||
| if (sheet.getLastRowNum() + dataSet.size() > entity.getMaxNum()) { | |||
| sheet = workbook.createSheet(); | |||
| index = 0; | |||
| } | |||
| Iterator<?> its = dataSet.iterator(); | |||
| while (its.hasNext()) { | |||
| Object t = its.next(); | |||
| try { | |||
| index += createCells(patriarch, index, t, excelParams, sheet, workbook, rowHeight); | |||
| } catch (Exception e) { | |||
| LOGGER.error(e.getMessage(), e); | |||
| throw new ExcelExportException(ExcelExportEnum.EXPORT_ERROR, e); | |||
| } | |||
| } | |||
| return workbook; | |||
| } | |||
| @Override | |||
| protected void insertDataToSheet(Workbook workbook, ExportParams entity, | |||
| List<ExcelExportEntity> entityList, Collection<?> dataSet, | |||
| Sheet sheet) { | |||
| try { | |||
| dataHanlder = entity.getDataHanlder(); | |||
| if (dataHanlder != null && dataHanlder.getNeedHandlerFields() != null) { | |||
| needHanlderList = Arrays.asList(dataHanlder.getNeedHandlerFields()); | |||
| } | |||
| // 创建表格样式 | |||
| setExcelExportStyler((IExcelExportStyler) entity.getStyle() | |||
| .getConstructor(Workbook.class).newInstance(workbook)); | |||
| patriarch = PoiExcelGraphDataUtil.getDrawingPatriarch(sheet); | |||
| List<ExcelExportEntity> excelParams = new ArrayList<ExcelExportEntity>(); | |||
| if (entity.isAddIndex()) { | |||
| excelParams.add(indexExcelEntity(entity)); | |||
| } | |||
| excelParams.addAll(entityList); | |||
| sortAllParams(excelParams); | |||
| this.index = entity.isCreateHeadRows() | |||
| ? createHeaderAndTitle(entity, sheet, workbook, excelParams) : 0; | |||
| titleHeight = index; | |||
| setCellWith(excelParams, sheet); | |||
| rowHeight = getRowHeight(excelParams); | |||
| setCurrentIndex(1); | |||
| } catch (Exception e) { | |||
| LOGGER.error(e.getMessage(), e); | |||
| throw new ExcelExportException(ExcelExportEnum.EXPORT_ERROR, e.getCause()); | |||
| } | |||
| } | |||
| public static ExcelBatchExportServer getExcelBatchExportServer(ExportParams entity, | |||
| Class<?> pojoClass) { | |||
| if (THREAD_LOCAL.get() == null) { | |||
| ExcelBatchExportServer batchServer = new ExcelBatchExportServer(); | |||
| batchServer.init(entity, pojoClass); | |||
| THREAD_LOCAL.set(batchServer); | |||
| } | |||
| return THREAD_LOCAL.get(); | |||
| } | |||
| public void closeExportBigExcel() { | |||
| if (entity.getFreezeCol() != 0) { | |||
| sheet.createFreezePane(entity.getFreezeCol(), 0, entity.getFreezeCol(), 0); | |||
| } | |||
| mergeCells(sheet, excelParams, titleHeight); | |||
| // 创建合计信息 | |||
| addStatisticsRow(getExcelExportStyler().getStyles(true, null), sheet); | |||
| THREAD_LOCAL.remove(); | |||
| } | |||
| } | |||
| package cn.afterturn.easypoi.excel.export; | |||
| import java.lang.reflect.Field; | |||
| import java.util.ArrayList; | |||
| import java.util.Arrays; | |||
| import java.util.Collection; | |||
| import java.util.Iterator; | |||
| import java.util.List; | |||
| import org.apache.poi.ss.usermodel.Drawing; | |||
| import org.apache.poi.ss.usermodel.Sheet; | |||
| import org.apache.poi.ss.usermodel.Workbook; | |||
| import org.apache.poi.xssf.streaming.SXSSFWorkbook; | |||
| import cn.afterturn.easypoi.excel.annotation.ExcelTarget; | |||
| import cn.afterturn.easypoi.excel.entity.ExportParams; | |||
| import cn.afterturn.easypoi.excel.entity.enmus.ExcelType; | |||
| import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity; | |||
| import cn.afterturn.easypoi.excel.export.styler.IExcelExportStyler; | |||
| import cn.afterturn.easypoi.exception.excel.ExcelExportException; | |||
| import cn.afterturn.easypoi.exception.excel.enums.ExcelExportEnum; | |||
| import cn.afterturn.easypoi.util.PoiExcelGraphDataUtil; | |||
| import cn.afterturn.easypoi.util.PoiPublicUtil; | |||
| /** | |||
| * 提供批次插入服务 | |||
| * @author JueYue | |||
| * 2016年8月29日 | |||
| */ | |||
| public class ExcelBatchExportService extends ExcelExportService { | |||
| private static ThreadLocal<ExcelBatchExportService> THREAD_LOCAL = new ThreadLocal<ExcelBatchExportService>(); | |||
| private Workbook workbook; | |||
| private Sheet sheet; | |||
| private List<ExcelExportEntity> excelParams; | |||
| private ExportParams entity; | |||
| private int titleHeight; | |||
| private Drawing patriarch; | |||
| private short rowHeight; | |||
| private int index; | |||
| public void init(ExportParams entity, Class<?> pojoClass) { | |||
| LOGGER.debug("ExcelBatchExportServer only support SXSSFWorkbook"); | |||
| entity.setType(ExcelType.XSSF); | |||
| workbook = new SXSSFWorkbook(); | |||
| this.entity = entity; | |||
| super.type = entity.getType(); | |||
| createSheet(workbook, entity, pojoClass); | |||
| if (entity.getMaxNum() == 0) { | |||
| entity.setMaxNum(1000000); | |||
| } | |||
| insertDataToSheet(workbook, entity, excelParams, null, sheet); | |||
| } | |||
| public void createSheet(Workbook workbook, ExportParams entity, Class<?> pojoClass) { | |||
| if (LOGGER.isDebugEnabled()) { | |||
| LOGGER.debug("Excel export start ,class is {}", pojoClass); | |||
| LOGGER.debug("Excel version is {}", | |||
| entity.getType().equals(ExcelType.HSSF) ? "03" : "07"); | |||
| } | |||
| if (workbook == null || entity == null || pojoClass == null) { | |||
| throw new ExcelExportException(ExcelExportEnum.PARAMETER_ERROR); | |||
| } | |||
| try { | |||
| excelParams = new ArrayList<ExcelExportEntity>(); | |||
| if (entity.isAddIndex()) { | |||
| excelParams.add(indexExcelEntity(entity)); | |||
| } | |||
| // 得到所有字段 | |||
| Field[] fileds = PoiPublicUtil.getClassFields(pojoClass); | |||
| ExcelTarget etarget = pojoClass.getAnnotation(ExcelTarget.class); | |||
| String targetId = etarget == null ? null : etarget.value(); | |||
| getAllExcelField(entity.getExclusions(), targetId, fileds, excelParams, pojoClass, | |||
| null, null); | |||
| sortAllParams(excelParams); | |||
| try { | |||
| sheet = workbook.createSheet(entity.getSheetName()); | |||
| } catch (Exception e) { | |||
| // 重复遍历,出现了重名现象,创建非指定的名称Sheet | |||
| sheet = workbook.createSheet(); | |||
| } | |||
| } catch (Exception e) { | |||
| throw new ExcelExportException(ExcelExportEnum.EXPORT_ERROR, e); | |||
| } | |||
| } | |||
| public Workbook appendData(Collection<?> dataSet) { | |||
| if (sheet.getLastRowNum() + dataSet.size() > entity.getMaxNum()) { | |||
| sheet = workbook.createSheet(); | |||
| index = 0; | |||
| } | |||
| Iterator<?> its = dataSet.iterator(); | |||
| while (its.hasNext()) { | |||
| Object t = its.next(); | |||
| try { | |||
| index += createCells(patriarch, index, t, excelParams, sheet, workbook, rowHeight); | |||
| } catch (Exception e) { | |||
| LOGGER.error(e.getMessage(), e); | |||
| throw new ExcelExportException(ExcelExportEnum.EXPORT_ERROR, e); | |||
| } | |||
| } | |||
| return workbook; | |||
| } | |||
| @Override | |||
| protected void insertDataToSheet(Workbook workbook, ExportParams entity, | |||
| List<ExcelExportEntity> entityList, Collection<?> dataSet, | |||
| Sheet sheet) { | |||
| try { | |||
| dataHanlder = entity.getDataHanlder(); | |||
| if (dataHanlder != null && dataHanlder.getNeedHandlerFields() != null) { | |||
| needHanlderList = Arrays.asList(dataHanlder.getNeedHandlerFields()); | |||
| } | |||
| // 创建表格样式 | |||
| setExcelExportStyler((IExcelExportStyler) entity.getStyle() | |||
| .getConstructor(Workbook.class).newInstance(workbook)); | |||
| patriarch = PoiExcelGraphDataUtil.getDrawingPatriarch(sheet); | |||
| List<ExcelExportEntity> excelParams = new ArrayList<ExcelExportEntity>(); | |||
| if (entity.isAddIndex()) { | |||
| excelParams.add(indexExcelEntity(entity)); | |||
| } | |||
| excelParams.addAll(entityList); | |||
| sortAllParams(excelParams); | |||
| this.index = entity.isCreateHeadRows() | |||
| ? createHeaderAndTitle(entity, sheet, workbook, excelParams) : 0; | |||
| titleHeight = index; | |||
| setCellWith(excelParams, sheet); | |||
| rowHeight = getRowHeight(excelParams); | |||
| setCurrentIndex(1); | |||
| } catch (Exception e) { | |||
| LOGGER.error(e.getMessage(), e); | |||
| throw new ExcelExportException(ExcelExportEnum.EXPORT_ERROR, e.getCause()); | |||
| } | |||
| } | |||
| public static ExcelBatchExportService getExcelBatchExportService(ExportParams entity, | |||
| Class<?> pojoClass) { | |||
| if (THREAD_LOCAL.get() == null) { | |||
| ExcelBatchExportService batchServer = new ExcelBatchExportService(); | |||
| batchServer.init(entity, pojoClass); | |||
| THREAD_LOCAL.set(batchServer); | |||
| } | |||
| return THREAD_LOCAL.get(); | |||
| } | |||
| public void closeExportBigExcel() { | |||
| if (entity.getFreezeCol() != 0) { | |||
| sheet.createFreezePane(entity.getFreezeCol(), 0, entity.getFreezeCol(), 0); | |||
| } | |||
| mergeCells(sheet, excelParams, titleHeight); | |||
| // 创建合计信息 | |||
| addStatisticsRow(getExcelExportStyler().getStyles(true, null), sheet); | |||
| THREAD_LOCAL.remove(); | |||
| } | |||
| } | |||
| @@ -1,267 +1,267 @@ | |||
| /** | |||
| * Copyright 2013-2015 JueYue (qrb.jueyue@gmail.com) | |||
| * | |||
| * Licensed under the Apache License, Version 2.0 (the "License"); | |||
| * you may not use this file except in compliance with the License. | |||
| * You may obtain a copy of the License at | |||
| * | |||
| * http://www.apache.org/licenses/LICENSE-2.0 | |||
| * | |||
| * Unless required by applicable law or agreed to in writing, software | |||
| * distributed under the License is distributed on an "AS IS" BASIS, | |||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
| * See the License for the specific language governing permissions and | |||
| * limitations under the License. | |||
| */ | |||
| package cn.afterturn.easypoi.excel.export; | |||
| import java.lang.reflect.Field; | |||
| import java.util.ArrayList; | |||
| import java.util.Arrays; | |||
| import java.util.Collection; | |||
| import java.util.Iterator; | |||
| import java.util.List; | |||
| import org.apache.commons.lang3.StringUtils; | |||
| import org.apache.poi.ss.usermodel.CellStyle; | |||
| import org.apache.poi.ss.usermodel.Drawing; | |||
| import org.apache.poi.ss.usermodel.Row; | |||
| import org.apache.poi.ss.usermodel.Sheet; | |||
| import org.apache.poi.ss.usermodel.Workbook; | |||
| import org.apache.poi.ss.util.CellRangeAddress; | |||
| import cn.afterturn.easypoi.excel.annotation.ExcelTarget; | |||
| import cn.afterturn.easypoi.excel.entity.ExportParams; | |||
| import cn.afterturn.easypoi.excel.entity.enmus.ExcelType; | |||
| import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity; | |||
| import cn.afterturn.easypoi.excel.export.base.BaseExportServer; | |||
| import cn.afterturn.easypoi.excel.export.styler.IExcelExportStyler; | |||
| import cn.afterturn.easypoi.exception.excel.ExcelExportException; | |||
| import cn.afterturn.easypoi.exception.excel.enums.ExcelExportEnum; | |||
| import cn.afterturn.easypoi.util.PoiExcelGraphDataUtil; | |||
| import cn.afterturn.easypoi.util.PoiPublicUtil; | |||
| /** | |||
| * Excel导出服务 | |||
| * | |||
| * @author JueYue 2014年6月17日 下午5:30:54 | |||
| */ | |||
| public class ExcelExportServer extends BaseExportServer { | |||
| // 最大行数,超过自动多Sheet | |||
| private static int MAX_NUM = 60000; | |||
| protected int createHeaderAndTitle(ExportParams entity, Sheet sheet, Workbook workbook, | |||
| List<ExcelExportEntity> excelParams) { | |||
| int rows = 0, fieldLength = getFieldLength(excelParams); | |||
| if (entity.getTitle() != null) { | |||
| rows += createHeaderRow(entity, sheet, workbook, fieldLength); | |||
| } | |||
| rows += createTitleRow(entity, sheet, workbook, rows, excelParams); | |||
| sheet.createFreezePane(0, rows, 0, rows); | |||
| return rows; | |||
| } | |||
| /** | |||
| * 创建 表头改变 | |||
| */ | |||
| public int createHeaderRow(ExportParams entity, Sheet sheet, Workbook workbook, | |||
| int fieldWidth) { | |||
| Row row = sheet.createRow(0); | |||
| row.setHeight(entity.getTitleHeight()); | |||
| createStringCell(row, 0, entity.getTitle(), | |||
| getExcelExportStyler().getHeaderStyle(entity.getHeaderColor()), null); | |||
| for (int i = 1; i <= fieldWidth; i++) { | |||
| createStringCell(row, i, "", | |||
| getExcelExportStyler().getHeaderStyle(entity.getHeaderColor()), null); | |||
| } | |||
| sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, fieldWidth)); | |||
| if (entity.getSecondTitle() != null) { | |||
| row = sheet.createRow(1); | |||
| row.setHeight(entity.getSecondTitleHeight()); | |||
| CellStyle style = workbook.createCellStyle(); | |||
| style.setAlignment(CellStyle.ALIGN_RIGHT); | |||
| createStringCell(row, 0, entity.getSecondTitle(), style, null); | |||
| for (int i = 1; i <= fieldWidth; i++) { | |||
| createStringCell(row, i, "", | |||
| getExcelExportStyler().getHeaderStyle(entity.getHeaderColor()), null); | |||
| } | |||
| sheet.addMergedRegion(new CellRangeAddress(1, 1, 0, fieldWidth)); | |||
| return 2; | |||
| } | |||
| return 1; | |||
| } | |||
| public void createSheet(Workbook workbook, ExportParams entity, Class<?> pojoClass, | |||
| Collection<?> dataSet) { | |||
| if (LOGGER.isDebugEnabled()) { | |||
| LOGGER.debug("Excel export start ,class is {}", pojoClass); | |||
| LOGGER.debug("Excel version is {}", | |||
| entity.getType().equals(ExcelType.HSSF) ? "03" : "07"); | |||
| } | |||
| if (workbook == null || entity == null || pojoClass == null || dataSet == null) { | |||
| throw new ExcelExportException(ExcelExportEnum.PARAMETER_ERROR); | |||
| } | |||
| try { | |||
| List<ExcelExportEntity> excelParams = new ArrayList<ExcelExportEntity>(); | |||
| // 得到所有字段 | |||
| Field[] fileds = PoiPublicUtil.getClassFields(pojoClass); | |||
| ExcelTarget etarget = pojoClass.getAnnotation(ExcelTarget.class); | |||
| String targetId = etarget == null ? null : etarget.value(); | |||
| getAllExcelField(entity.getExclusions(), targetId, fileds, excelParams, pojoClass, | |||
| null, null); | |||
| //获取所有参数后,后面的逻辑判断就一致了 | |||
| createSheetForMap(workbook, entity, excelParams, dataSet); | |||
| } catch (Exception e) { | |||
| LOGGER.error(e.getMessage(), e); | |||
| throw new ExcelExportException(ExcelExportEnum.EXPORT_ERROR, e.getCause()); | |||
| } | |||
| } | |||
| public void createSheetForMap(Workbook workbook, ExportParams entity, | |||
| List<ExcelExportEntity> entityList, Collection<?> dataSet) { | |||
| if (LOGGER.isDebugEnabled()) { | |||
| LOGGER.debug("Excel version is {}", | |||
| entity.getType().equals(ExcelType.HSSF) ? "03" : "07"); | |||
| } | |||
| if (workbook == null || entity == null || entityList == null || dataSet == null) { | |||
| throw new ExcelExportException(ExcelExportEnum.PARAMETER_ERROR); | |||
| } | |||
| super.type = entity.getType(); | |||
| if (type.equals(ExcelType.XSSF)) { | |||
| MAX_NUM = 1000000; | |||
| } | |||
| if (entity.getMaxNum() > 0) { | |||
| MAX_NUM = entity.getMaxNum(); | |||
| } | |||
| Sheet sheet = null; | |||
| try { | |||
| sheet = workbook.createSheet(entity.getSheetName()); | |||
| } catch (Exception e) { | |||
| // 重复遍历,出现了重名现象,创建非指定的名称Sheet | |||
| sheet = workbook.createSheet(); | |||
| } | |||
| insertDataToSheet(workbook, entity, entityList, dataSet, sheet); | |||
| } | |||
| protected void insertDataToSheet(Workbook workbook, ExportParams entity, | |||
| List<ExcelExportEntity> entityList, Collection<?> dataSet, | |||
| Sheet sheet) { | |||
| try { | |||
| dataHanlder = entity.getDataHanlder(); | |||
| if (dataHanlder != null && dataHanlder.getNeedHandlerFields() != null) { | |||
| needHanlderList = Arrays.asList(dataHanlder.getNeedHandlerFields()); | |||
| } | |||
| // 创建表格样式 | |||
| setExcelExportStyler((IExcelExportStyler) entity.getStyle() | |||
| .getConstructor(Workbook.class).newInstance(workbook)); | |||
| Drawing patriarch = PoiExcelGraphDataUtil.getDrawingPatriarch(sheet); | |||
| List<ExcelExportEntity> excelParams = new ArrayList<ExcelExportEntity>(); | |||
| if (entity.isAddIndex()) { | |||
| excelParams.add(indexExcelEntity(entity)); | |||
| } | |||
| excelParams.addAll(entityList); | |||
| sortAllParams(excelParams); | |||
| int index = entity.isCreateHeadRows() | |||
| ? createHeaderAndTitle(entity, sheet, workbook, excelParams) : 0; | |||
| int titleHeight = index; | |||
| setCellWith(excelParams, sheet); | |||
| short rowHeight = entity.getHeight() > 0 ? entity.getHeight() : getRowHeight(excelParams); | |||
| setCurrentIndex(1); | |||
| Iterator<?> its = dataSet.iterator(); | |||
| List<Object> tempList = new ArrayList<Object>(); | |||
| while (its.hasNext()) { | |||
| Object t = its.next(); | |||
| index += createCells(patriarch, index, t, excelParams, sheet, workbook, rowHeight); | |||
| tempList.add(t); | |||
| if (index >= MAX_NUM) { | |||
| break; | |||
| } | |||
| } | |||
| if (entity.getFreezeCol() != 0) { | |||
| sheet.createFreezePane(entity.getFreezeCol(), 0, entity.getFreezeCol(), 0); | |||
| } | |||
| mergeCells(sheet, excelParams, titleHeight); | |||
| its = dataSet.iterator(); | |||
| for (int i = 0, le = tempList.size(); i < le; i++) { | |||
| its.next(); | |||
| its.remove(); | |||
| } | |||
| if (LOGGER.isDebugEnabled()) { | |||
| LOGGER.debug("List data more than max ,data size is {}", | |||
| dataSet.size()); | |||
| } | |||
| // 发现还有剩余list 继续循环创建Sheet | |||
| if (dataSet.size() > 0) { | |||
| createSheetForMap(workbook, entity, entityList, dataSet); | |||
| } else { | |||
| // 创建合计信息 | |||
| addStatisticsRow(getExcelExportStyler().getStyles(true, null), sheet); | |||
| } | |||
| } catch (Exception e) { | |||
| LOGGER.error(e.getMessage(), e); | |||
| throw new ExcelExportException(ExcelExportEnum.EXPORT_ERROR, e.getCause()); | |||
| } | |||
| } | |||
| /** | |||
| * 创建表头 | |||
| */ | |||
| private int createTitleRow(ExportParams title, Sheet sheet, Workbook workbook, int index, | |||
| List<ExcelExportEntity> excelParams) { | |||
| Row row = sheet.createRow(index); | |||
| int rows = getRowNums(excelParams); | |||
| row.setHeight((short) 450); | |||
| Row listRow = null; | |||
| if (rows == 2) { | |||
| listRow = sheet.createRow(index + 1); | |||
| listRow.setHeight((short) 450); | |||
| } | |||
| int cellIndex = 0; | |||
| int groupCellLength = 0; | |||
| CellStyle titleStyle = getExcelExportStyler().getTitleStyle(title.getColor()); | |||
| for (int i = 0, exportFieldTitleSize = excelParams.size(); i < exportFieldTitleSize; i++) { | |||
| ExcelExportEntity entity = excelParams.get(i); | |||
| // 加入换了groupName或者结束就,就把之前的那个换行 | |||
| if (StringUtils.isBlank(entity.getGroupName()) || !entity.getGroupName().equals(excelParams.get(i - 1).getGroupName())) { | |||
| if(groupCellLength > 1){ | |||
| sheet.addMergedRegion(new CellRangeAddress(index, index, cellIndex - groupCellLength, cellIndex - 1)); | |||
| } | |||
| groupCellLength = 0; | |||
| } | |||
| if (StringUtils.isNotBlank(entity.getGroupName())) { | |||
| createStringCell(row, cellIndex, entity.getGroupName(), titleStyle, entity); | |||
| createStringCell(listRow, cellIndex, entity.getName(), titleStyle, entity); | |||
| groupCellLength++; | |||
| } else if (StringUtils.isNotBlank(entity.getName())) { | |||
| createStringCell(row, cellIndex, entity.getName(), titleStyle, entity); | |||
| } | |||
| if (entity.getList() != null) { | |||
| List<ExcelExportEntity> sTitel = entity.getList(); | |||
| if (StringUtils.isNotBlank(entity.getName())) { | |||
| sheet.addMergedRegion(new CellRangeAddress(index, index, cellIndex, cellIndex + sTitel.size() - 1)); | |||
| } | |||
| for (int j = 0, size = sTitel.size(); j < size; j++) { | |||
| createStringCell(rows == 2 ? listRow : row, cellIndex, sTitel.get(j).getName(), | |||
| titleStyle, entity); | |||
| cellIndex++; | |||
| } | |||
| cellIndex--; | |||
| } else if (rows == 2 && StringUtils.isBlank(entity.getGroupName())) { | |||
| createStringCell(listRow, cellIndex, "", titleStyle, entity); | |||
| sheet.addMergedRegion(new CellRangeAddress(index, index + 1, cellIndex, cellIndex)); | |||
| } | |||
| cellIndex++; | |||
| } | |||
| if (groupCellLength > 1) { | |||
| sheet.addMergedRegion(new CellRangeAddress(index, index, cellIndex - groupCellLength, cellIndex - 1)); | |||
| } | |||
| return rows; | |||
| } | |||
| } | |||
| /** | |||
| * Copyright 2013-2015 JueYue (qrb.jueyue@gmail.com) | |||
| * | |||
| * Licensed under the Apache License, Version 2.0 (the "License"); | |||
| * you may not use this file except in compliance with the License. | |||
| * You may obtain a copy of the License at | |||
| * | |||
| * http://www.apache.org/licenses/LICENSE-2.0 | |||
| * | |||
| * Unless required by applicable law or agreed to in writing, software | |||
| * distributed under the License is distributed on an "AS IS" BASIS, | |||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
| * See the License for the specific language governing permissions and | |||
| * limitations under the License. | |||
| */ | |||
| package cn.afterturn.easypoi.excel.export; | |||
| import java.lang.reflect.Field; | |||
| import java.util.ArrayList; | |||
| import java.util.Arrays; | |||
| import java.util.Collection; | |||
| import java.util.Iterator; | |||
| import java.util.List; | |||
| import org.apache.commons.lang3.StringUtils; | |||
| import org.apache.poi.ss.usermodel.CellStyle; | |||
| import org.apache.poi.ss.usermodel.Drawing; | |||
| import org.apache.poi.ss.usermodel.Row; | |||
| import org.apache.poi.ss.usermodel.Sheet; | |||
| import org.apache.poi.ss.usermodel.Workbook; | |||
| import org.apache.poi.ss.util.CellRangeAddress; | |||
| import cn.afterturn.easypoi.excel.annotation.ExcelTarget; | |||
| import cn.afterturn.easypoi.excel.entity.ExportParams; | |||
| import cn.afterturn.easypoi.excel.entity.enmus.ExcelType; | |||
| import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity; | |||
| import cn.afterturn.easypoi.excel.export.base.BaseExportService; | |||
| import cn.afterturn.easypoi.excel.export.styler.IExcelExportStyler; | |||
| import cn.afterturn.easypoi.exception.excel.ExcelExportException; | |||
| import cn.afterturn.easypoi.exception.excel.enums.ExcelExportEnum; | |||
| import cn.afterturn.easypoi.util.PoiExcelGraphDataUtil; | |||
| import cn.afterturn.easypoi.util.PoiPublicUtil; | |||
| /** | |||
| * Excel导出服务 | |||
| * | |||
| * @author JueYue 2014年6月17日 下午5:30:54 | |||
| */ | |||
| public class ExcelExportService extends BaseExportService { | |||
| // 最大行数,超过自动多Sheet | |||
| private static int MAX_NUM = 60000; | |||
| protected int createHeaderAndTitle(ExportParams entity, Sheet sheet, Workbook workbook, | |||
| List<ExcelExportEntity> excelParams) { | |||
| int rows = 0, fieldLength = getFieldLength(excelParams); | |||
| if (entity.getTitle() != null) { | |||
| rows += createHeaderRow(entity, sheet, workbook, fieldLength); | |||
| } | |||
| rows += createTitleRow(entity, sheet, workbook, rows, excelParams); | |||
| sheet.createFreezePane(0, rows, 0, rows); | |||
| return rows; | |||
| } | |||
| /** | |||
| * 创建 表头改变 | |||
| */ | |||
| public int createHeaderRow(ExportParams entity, Sheet sheet, Workbook workbook, | |||
| int fieldWidth) { | |||
| Row row = sheet.createRow(0); | |||
| row.setHeight(entity.getTitleHeight()); | |||
| createStringCell(row, 0, entity.getTitle(), | |||
| getExcelExportStyler().getHeaderStyle(entity.getHeaderColor()), null); | |||
| for (int i = 1; i <= fieldWidth; i++) { | |||
| createStringCell(row, i, "", | |||
| getExcelExportStyler().getHeaderStyle(entity.getHeaderColor()), null); | |||
| } | |||
| sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, fieldWidth)); | |||
| if (entity.getSecondTitle() != null) { | |||
| row = sheet.createRow(1); | |||
| row.setHeight(entity.getSecondTitleHeight()); | |||
| CellStyle style = workbook.createCellStyle(); | |||
| style.setAlignment(CellStyle.ALIGN_RIGHT); | |||
| createStringCell(row, 0, entity.getSecondTitle(), style, null); | |||
| for (int i = 1; i <= fieldWidth; i++) { | |||
| createStringCell(row, i, "", | |||
| getExcelExportStyler().getHeaderStyle(entity.getHeaderColor()), null); | |||
| } | |||
| sheet.addMergedRegion(new CellRangeAddress(1, 1, 0, fieldWidth)); | |||
| return 2; | |||
| } | |||
| return 1; | |||
| } | |||
| public void createSheet(Workbook workbook, ExportParams entity, Class<?> pojoClass, | |||
| Collection<?> dataSet) { | |||
| if (LOGGER.isDebugEnabled()) { | |||
| LOGGER.debug("Excel export start ,class is {}", pojoClass); | |||
| LOGGER.debug("Excel version is {}", | |||
| entity.getType().equals(ExcelType.HSSF) ? "03" : "07"); | |||
| } | |||
| if (workbook == null || entity == null || pojoClass == null || dataSet == null) { | |||
| throw new ExcelExportException(ExcelExportEnum.PARAMETER_ERROR); | |||
| } | |||
| try { | |||
| List<ExcelExportEntity> excelParams = new ArrayList<ExcelExportEntity>(); | |||
| // 得到所有字段 | |||
| Field[] fileds = PoiPublicUtil.getClassFields(pojoClass); | |||
| ExcelTarget etarget = pojoClass.getAnnotation(ExcelTarget.class); | |||
| String targetId = etarget == null ? null : etarget.value(); | |||
| getAllExcelField(entity.getExclusions(), targetId, fileds, excelParams, pojoClass, | |||
| null, null); | |||
| //获取所有参数后,后面的逻辑判断就一致了 | |||
| createSheetForMap(workbook, entity, excelParams, dataSet); | |||
| } catch (Exception e) { | |||
| LOGGER.error(e.getMessage(), e); | |||
| throw new ExcelExportException(ExcelExportEnum.EXPORT_ERROR, e.getCause()); | |||
| } | |||
| } | |||
| public void createSheetForMap(Workbook workbook, ExportParams entity, | |||
| List<ExcelExportEntity> entityList, Collection<?> dataSet) { | |||
| if (LOGGER.isDebugEnabled()) { | |||
| LOGGER.debug("Excel version is {}", | |||
| entity.getType().equals(ExcelType.HSSF) ? "03" : "07"); | |||
| } | |||
| if (workbook == null || entity == null || entityList == null || dataSet == null) { | |||
| throw new ExcelExportException(ExcelExportEnum.PARAMETER_ERROR); | |||
| } | |||
| super.type = entity.getType(); | |||
| if (type.equals(ExcelType.XSSF)) { | |||
| MAX_NUM = 1000000; | |||
| } | |||
| if (entity.getMaxNum() > 0) { | |||
| MAX_NUM = entity.getMaxNum(); | |||
| } | |||
| Sheet sheet = null; | |||
| try { | |||
| sheet = workbook.createSheet(entity.getSheetName()); | |||
| } catch (Exception e) { | |||
| // 重复遍历,出现了重名现象,创建非指定的名称Sheet | |||
| sheet = workbook.createSheet(); | |||
| } | |||
| insertDataToSheet(workbook, entity, entityList, dataSet, sheet); | |||
| } | |||
| protected void insertDataToSheet(Workbook workbook, ExportParams entity, | |||
| List<ExcelExportEntity> entityList, Collection<?> dataSet, | |||
| Sheet sheet) { | |||
| try { | |||
| dataHanlder = entity.getDataHanlder(); | |||
| if (dataHanlder != null && dataHanlder.getNeedHandlerFields() != null) { | |||
| needHanlderList = Arrays.asList(dataHanlder.getNeedHandlerFields()); | |||
| } | |||
| // 创建表格样式 | |||
| setExcelExportStyler((IExcelExportStyler) entity.getStyle() | |||
| .getConstructor(Workbook.class).newInstance(workbook)); | |||
| Drawing patriarch = PoiExcelGraphDataUtil.getDrawingPatriarch(sheet); | |||
| List<ExcelExportEntity> excelParams = new ArrayList<ExcelExportEntity>(); | |||
| if (entity.isAddIndex()) { | |||
| excelParams.add(indexExcelEntity(entity)); | |||
| } | |||
| excelParams.addAll(entityList); | |||
| sortAllParams(excelParams); | |||
| int index = entity.isCreateHeadRows() | |||
| ? createHeaderAndTitle(entity, sheet, workbook, excelParams) : 0; | |||
| int titleHeight = index; | |||
| setCellWith(excelParams, sheet); | |||
| short rowHeight = entity.getHeight() > 0 ? entity.getHeight() : getRowHeight(excelParams); | |||
| setCurrentIndex(1); | |||
| Iterator<?> its = dataSet.iterator(); | |||
| List<Object> tempList = new ArrayList<Object>(); | |||
| while (its.hasNext()) { | |||
| Object t = its.next(); | |||
| index += createCells(patriarch, index, t, excelParams, sheet, workbook, rowHeight); | |||
| tempList.add(t); | |||
| if (index >= MAX_NUM) { | |||
| break; | |||
| } | |||
| } | |||
| if (entity.getFreezeCol() != 0) { | |||
| sheet.createFreezePane(entity.getFreezeCol(), 0, entity.getFreezeCol(), 0); | |||
| } | |||
| mergeCells(sheet, excelParams, titleHeight); | |||
| its = dataSet.iterator(); | |||
| for (int i = 0, le = tempList.size(); i < le; i++) { | |||
| its.next(); | |||
| its.remove(); | |||
| } | |||
| if (LOGGER.isDebugEnabled()) { | |||
| LOGGER.debug("List data more than max ,data size is {}", | |||
| dataSet.size()); | |||
| } | |||
| // 发现还有剩余list 继续循环创建Sheet | |||
| if (dataSet.size() > 0) { | |||
| createSheetForMap(workbook, entity, entityList, dataSet); | |||
| } else { | |||
| // 创建合计信息 | |||
| addStatisticsRow(getExcelExportStyler().getStyles(true, null), sheet); | |||
| } | |||
| } catch (Exception e) { | |||
| LOGGER.error(e.getMessage(), e); | |||
| throw new ExcelExportException(ExcelExportEnum.EXPORT_ERROR, e.getCause()); | |||
| } | |||
| } | |||
| /** | |||
| * 创建表头 | |||
| */ | |||
| private int createTitleRow(ExportParams title, Sheet sheet, Workbook workbook, int index, | |||
| List<ExcelExportEntity> excelParams) { | |||
| Row row = sheet.createRow(index); | |||
| int rows = getRowNums(excelParams); | |||
| row.setHeight((short) 450); | |||
| Row listRow = null; | |||
| if (rows == 2) { | |||
| listRow = sheet.createRow(index + 1); | |||
| listRow.setHeight((short) 450); | |||
| } | |||
| int cellIndex = 0; | |||
| int groupCellLength = 0; | |||
| CellStyle titleStyle = getExcelExportStyler().getTitleStyle(title.getColor()); | |||
| for (int i = 0, exportFieldTitleSize = excelParams.size(); i < exportFieldTitleSize; i++) { | |||
| ExcelExportEntity entity = excelParams.get(i); | |||
| // 加入换了groupName或者结束就,就把之前的那个换行 | |||
| if (StringUtils.isBlank(entity.getGroupName()) || !entity.getGroupName().equals(excelParams.get(i - 1).getGroupName())) { | |||
| if(groupCellLength > 1){ | |||
| sheet.addMergedRegion(new CellRangeAddress(index, index, cellIndex - groupCellLength, cellIndex - 1)); | |||
| } | |||
| groupCellLength = 0; | |||
| } | |||
| if (StringUtils.isNotBlank(entity.getGroupName())) { | |||
| createStringCell(row, cellIndex, entity.getGroupName(), titleStyle, entity); | |||
| createStringCell(listRow, cellIndex, entity.getName(), titleStyle, entity); | |||
| groupCellLength++; | |||
| } else if (StringUtils.isNotBlank(entity.getName())) { | |||
| createStringCell(row, cellIndex, entity.getName(), titleStyle, entity); | |||
| } | |||
| if (entity.getList() != null) { | |||
| List<ExcelExportEntity> sTitel = entity.getList(); | |||
| if (StringUtils.isNotBlank(entity.getName())) { | |||
| sheet.addMergedRegion(new CellRangeAddress(index, index, cellIndex, cellIndex + sTitel.size() - 1)); | |||
| } | |||
| for (int j = 0, size = sTitel.size(); j < size; j++) { | |||
| createStringCell(rows == 2 ? listRow : row, cellIndex, sTitel.get(j).getName(), | |||
| titleStyle, entity); | |||
| cellIndex++; | |||
| } | |||
| cellIndex--; | |||
| } else if (rows == 2 && StringUtils.isBlank(entity.getGroupName())) { | |||
| createStringCell(listRow, cellIndex, "", titleStyle, entity); | |||
| sheet.addMergedRegion(new CellRangeAddress(index, index + 1, cellIndex, cellIndex)); | |||
| } | |||
| cellIndex++; | |||
| } | |||
| if (groupCellLength > 1) { | |||
| sheet.addMergedRegion(new CellRangeAddress(index, index, cellIndex - groupCellLength, cellIndex - 1)); | |||
| } | |||
| return rows; | |||
| } | |||
| } | |||
| @@ -54,7 +54,7 @@ import cn.afterturn.easypoi.util.PoiPublicUtil; | |||
| * @author JueYue 2014年6月17日 下午6:15:13 | |||
| */ | |||
| @SuppressWarnings("unchecked") | |||
| public abstract class BaseExportServer extends ExportCommonServer { | |||
| public abstract class BaseExportService extends ExportCommonService { | |||
| private int currentIndex = 0; | |||
| @@ -29,7 +29,6 @@ import java.util.HashMap; | |||
| import java.util.Iterator; | |||
| import java.util.List; | |||
| import java.util.Map; | |||
| import java.util.Set; | |||
| import org.apache.commons.lang3.StringUtils; | |||
| import org.apache.commons.lang3.builder.ReflectionToStringBuilder; | |||
| @@ -55,9 +54,9 @@ import cn.afterturn.easypoi.util.PoiReflectorUtil; | |||
| * @author JueYue 2014年8月9日 下午11:01:32 | |||
| */ | |||
| @SuppressWarnings("rawtypes") | |||
| public class ExportCommonServer { | |||
| public class ExportCommonService { | |||
| protected static final Logger LOGGER = LoggerFactory.getLogger(ExportCommonServer.class); | |||
| protected static final Logger LOGGER = LoggerFactory.getLogger(ExportCommonService.class); | |||
| protected IExcelDataHandler dataHanlder; | |||
| @@ -47,7 +47,7 @@ import cn.afterturn.easypoi.excel.entity.TemplateExportParams; | |||
| import cn.afterturn.easypoi.excel.entity.enmus.ExcelType; | |||
| import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity; | |||
| import cn.afterturn.easypoi.excel.entity.params.ExcelForEachParams; | |||
| import cn.afterturn.easypoi.excel.export.base.BaseExportServer; | |||
| import cn.afterturn.easypoi.excel.export.base.BaseExportService; | |||
| import cn.afterturn.easypoi.excel.export.styler.IExcelExportStyler; | |||
| import cn.afterturn.easypoi.excel.export.template.TemplateSumHanlder.TemplateSumEntity; | |||
| import cn.afterturn.easypoi.excel.html.helper.MergedRegionHelper; | |||
| @@ -64,7 +64,7 @@ import cn.afterturn.easypoi.util.PoiSheetUtility; | |||
| * 2013-10-17 | |||
| * @version 1.0 | |||
| */ | |||
| public final class ExcelExportOfTemplateUtil extends BaseExportServer { | |||
| public final class ExcelExportOfTemplateUtil extends BaseExportService { | |||
| private static final Logger LOGGER = LoggerFactory | |||
| .getLogger(ExcelExportOfTemplateUtil.class); | |||
| @@ -1,313 +1,311 @@ | |||
| package cn.afterturn.easypoi.excel.html; | |||
| import java.io.File; | |||
| import java.io.FileOutputStream; | |||
| import java.text.SimpleDateFormat; | |||
| import java.util.Date; | |||
| import java.util.Formatter; | |||
| import java.util.HashMap; | |||
| import java.util.Iterator; | |||
| import java.util.Map; | |||
| import org.apache.commons.lang3.StringUtils; | |||
| import org.apache.poi.hssf.usermodel.HSSFSheet; | |||
| import org.apache.poi.hssf.usermodel.HSSFWorkbook; | |||
| import org.apache.poi.ss.usermodel.Cell; | |||
| import org.apache.poi.ss.usermodel.CellStyle; | |||
| import org.apache.poi.ss.usermodel.PictureData; | |||
| import org.apache.poi.ss.usermodel.Row; | |||
| import org.apache.poi.ss.usermodel.Sheet; | |||
| import org.apache.poi.ss.usermodel.Workbook; | |||
| import org.apache.poi.xssf.usermodel.XSSFSheet; | |||
| import org.apache.poi.xssf.usermodel.XSSFWorkbook; | |||
| import org.slf4j.Logger; | |||
| import org.slf4j.LoggerFactory; | |||
| import sun.misc.BASE64Encoder; | |||
| import cn.afterturn.easypoi.excel.entity.ExcelToHtmlParams; | |||
| import cn.afterturn.easypoi.excel.html.helper.CellValueHelper; | |||
| import cn.afterturn.easypoi.excel.html.helper.MergedRegionHelper; | |||
| import cn.afterturn.easypoi.excel.html.helper.StylerHelper; | |||
| import cn.afterturn.easypoi.util.PoiPublicUtil; | |||
| /** | |||
| * Excel转换成Html 服务 | |||
| * @author JueYue | |||
| * 2015年5月10日 上午11:41:15 | |||
| */ | |||
| public class ExcelToHtmlServer { | |||
| private static final Logger LOGGER = LoggerFactory | |||
| .getLogger(ExcelToHtmlServer.class); | |||
| private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy_MM_dd"); | |||
| private String today; | |||
| private Workbook wb; | |||
| private int sheetNum; | |||
| private int cssRandom; | |||
| /*是不是完成界面*/ | |||
| private boolean completeHTML; | |||
| private Formatter out; | |||
| /*已经完成范围处理*/ | |||
| private boolean gotBounds; | |||
| private int firstColumn; | |||
| private int endColumn; | |||
| private String imageCachePath; | |||
| private static final String COL_HEAD_CLASS = "colHeader"; | |||
| //private static final String ROW_HEAD_CLASS = "rowHeader"; | |||
| private static final String DEFAULTS_CLASS = "excelDefaults"; | |||
| //图片缓存 | |||
| private Map<String, PictureData> pictures = new HashMap<String, PictureData>(); | |||
| public ExcelToHtmlServer(ExcelToHtmlParams params) { | |||
| this.wb = params.getWb(); | |||
| this.completeHTML = params.isCompleteHTML(); | |||
| this.sheetNum = params.getSheetNum(); | |||
| cssRandom = (int) Math.ceil(Math.random() * 1000); | |||
| this.imageCachePath = params.getPath(); | |||
| today = new SimpleDateFormat("yyyy_MM_dd").format(new Date()); | |||
| } | |||
| public String printPage() { | |||
| try { | |||
| ensureOut(); | |||
| if (completeHTML) { | |||
| out.format("<!DOCTYPE HTML>%n"); | |||
| out.format("<html>%n"); | |||
| out.format( | |||
| "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">%n"); | |||
| out.format("<head>%n"); | |||
| } | |||
| if (StringUtils.isNotEmpty(imageCachePath)) { | |||
| getPictures(); | |||
| } | |||
| new StylerHelper(wb, out, sheetNum, cssRandom); | |||
| if (completeHTML) { | |||
| out.format("</head>%n"); | |||
| out.format("<body>%n"); | |||
| } | |||
| print(); | |||
| if (completeHTML) { | |||
| out.format("</body>%n"); | |||
| out.format("</html>%n"); | |||
| } | |||
| return out.toString(); | |||
| } catch (Exception e) { | |||
| LOGGER.error(e.getMessage(), e); | |||
| } finally { | |||
| if (out != null) { | |||
| out.close(); | |||
| } | |||
| } | |||
| return null; | |||
| } | |||
| /** | |||
| * 获取Sheet缓存的图片 | |||
| */ | |||
| private void getPictures() { | |||
| if (wb instanceof XSSFWorkbook) { | |||
| pictures = PoiPublicUtil.getSheetPictrues07((XSSFSheet) wb.getSheetAt(sheetNum), | |||
| (XSSFWorkbook) wb); | |||
| } else { | |||
| pictures = PoiPublicUtil.getSheetPictrues03((HSSFSheet) wb.getSheetAt(sheetNum), | |||
| (HSSFWorkbook) wb); | |||
| } | |||
| } | |||
| private void print() { | |||
| printSheets(); | |||
| } | |||
| private void ensureOut() { | |||
| if (out == null) { | |||
| out = new Formatter(new StringBuilder()); | |||
| } | |||
| } | |||
| private void printSheets() { | |||
| Sheet sheet = wb.getSheetAt(sheetNum); | |||
| printSheet(sheet); | |||
| } | |||
| private void printSheet(Sheet sheet) { | |||
| out.format("<table class='%s' width='%s'>%n", DEFAULTS_CLASS, getTableWidth(sheet)); | |||
| printCols(sheet); | |||
| printSheetContent(sheet); | |||
| out.format("</table>%n"); | |||
| } | |||
| private void printCols(Sheet sheet) { | |||
| //out.format("<col/>%n"); | |||
| ensureColumnBounds(sheet); | |||
| for (int i = firstColumn; i < endColumn; i++) { | |||
| out.format("<col style='width:%spx;' />%n", sheet.getColumnWidth(i) / 32); | |||
| } | |||
| } | |||
| private int getTableWidth(Sheet sheet) { | |||
| ensureColumnBounds(sheet); | |||
| int width = 0; | |||
| for (int i = firstColumn; i < endColumn; i++) { | |||
| width = width + (sheet.getColumnWidth(i) / 32); | |||
| } | |||
| return width; | |||
| } | |||
| private void ensureColumnBounds(Sheet sheet) { | |||
| if (gotBounds) { | |||
| return; | |||
| } | |||
| Iterator<Row> iter = sheet.rowIterator(); | |||
| firstColumn = (iter.hasNext() ? Integer.MAX_VALUE : 0); | |||
| endColumn = 0; | |||
| while (iter.hasNext()) { | |||
| Row row = iter.next(); | |||
| short firstCell = row.getFirstCellNum(); | |||
| if (firstCell >= 0) { | |||
| firstColumn = Math.min(firstColumn, firstCell); | |||
| endColumn = Math.max(endColumn, row.getLastCellNum()); | |||
| } | |||
| } | |||
| gotBounds = true; | |||
| } | |||
| @SuppressWarnings("unused") | |||
| /**本来是用来生成 A,B 那个列名称的**/ | |||
| private void printColumnHeads(Sheet sheet) { | |||
| out.format("<thead>%n"); | |||
| out.format(" <tr class=%s>%n", COL_HEAD_CLASS); | |||
| out.format(" <th class=%s>◊</th>%n", COL_HEAD_CLASS); | |||
| StringBuilder colName = new StringBuilder(); | |||
| for (int i = firstColumn; i < endColumn; i++) { | |||
| colName.setLength(0); | |||
| int cnum = i; | |||
| do { | |||
| colName.insert(0, (char) ('A' + cnum % 26)); | |||
| cnum /= 26; | |||
| } while (cnum > 0); | |||
| out.format(" <th class=%s>%s</th>%n", COL_HEAD_CLASS, colName); | |||
| } | |||
| out.format(" </tr>%n"); | |||
| out.format("</thead>%n"); | |||
| } | |||
| private void printSheetContent(Sheet sheet) { | |||
| //printColumnHeads(sheet); | |||
| MergedRegionHelper mergedRegionHelper = new MergedRegionHelper(sheet); | |||
| CellValueHelper cellValueHelper = new CellValueHelper(wb, cssRandom); | |||
| out.format("<tbody>%n"); | |||
| Iterator<Row> rows = sheet.rowIterator(); | |||
| int rowIndex = 1; | |||
| while (rows.hasNext()) { | |||
| Row row = rows.next(); | |||
| out.format(" <tr style='height:%spx;'>%n", row.getHeight() / 15); | |||
| //out.format(" <td class='%s'>%d</td>%n", ROW_HEAD_CLASS, row.getRowNum() + 1); | |||
| for (int i = firstColumn; i < endColumn; i++) { | |||
| if (mergedRegionHelper.isNeedCreate(rowIndex, i)) { | |||
| String content = " "; | |||
| CellStyle style = null; | |||
| if (i >= row.getFirstCellNum() && i < row.getLastCellNum()) { | |||
| Cell cell = row.getCell(i); | |||
| if (cell != null) { | |||
| style = cell.getCellStyle(); | |||
| content = cellValueHelper.getHtmlValue(cell); | |||
| } | |||
| } | |||
| if (pictures.containsKey((rowIndex - 1) + "_" + i)) { | |||
| content = "<img src='data:image/"+PoiPublicUtil.getFileExtendName(pictures.get((rowIndex - 1) + "_" + i).getData()) | |||
| +";base64," + getImageSrc(pictures.get((rowIndex - 1) + "_" + i)) | |||
| + "' style='max-width: " | |||
| + getImageMaxWidth( | |||
| mergedRegionHelper.getRowAndColSpan(rowIndex, i), i, sheet) | |||
| + "px;' />"; | |||
| } | |||
| if (mergedRegionHelper.isMergedRegion(rowIndex, i)) { | |||
| Integer[] rowAndColSpan = mergedRegionHelper.getRowAndColSpan(rowIndex, i); | |||
| out.format(" <td rowspan='%s' colspan='%s' class='%s' >%s</td>%n", | |||
| rowAndColSpan[0], rowAndColSpan[1], styleName(style), content); | |||
| } else { | |||
| out.format(" <td class='%s'>%s</td>%n", styleName(style), content); | |||
| } | |||
| } | |||
| } | |||
| out.format(" </tr>%n"); | |||
| rowIndex++; | |||
| } | |||
| out.format("</tbody>%n"); | |||
| } | |||
| /** | |||
| * 获取图片最大宽度 | |||
| * @param colIndex | |||
| * @param sheet | |||
| * @param rowAndColSpan | |||
| * @return | |||
| */ | |||
| private int getImageMaxWidth(Integer[] rowAndColSpan, int colIndex, Sheet sheet) { | |||
| if (rowAndColSpan == null) { | |||
| return sheet.getColumnWidth(colIndex) / 32; | |||
| } | |||
| int maxWidth = 0; | |||
| for (int i = 0; i < rowAndColSpan[1]; i++) { | |||
| maxWidth += sheet.getColumnWidth(colIndex + i) / 32; | |||
| } | |||
| return maxWidth; | |||
| } | |||
| /** | |||
| * 获取图片路径 | |||
| * @param pictureData | |||
| * @return | |||
| */ | |||
| private String getImageSrc(PictureData pictureData) { | |||
| if (pictureData == null) { | |||
| return ""; | |||
| } | |||
| byte[] data = pictureData.getData(); | |||
| //直接输出到HTML使用BASE64Encoder | |||
| // 加密 | |||
| BASE64Encoder encoder = new BASE64Encoder(); | |||
| return encoder.encode(data); | |||
| /*String fileName = "pic" + Math.round(Math.random() * 100000000000L); | |||
| fileName += "." + PoiPublicUtil.getFileExtendName(data); | |||
| if (!imageCachePath.startsWith("/") && !imageCachePath.contains(":")) { | |||
| imageCachePath = PoiPublicUtil.getWebRootPath(imageCachePath); | |||
| } | |||
| File savefile = new File(imageCachePath + "/" + today); | |||
| if (!savefile.exists()) { | |||
| savefile.mkdirs(); | |||
| } | |||
| savefile = new File(imageCachePath + "/" + today + "/" + fileName); | |||
| FileOutputStream fos = null; | |||
| try { | |||
| fos = new FileOutputStream(savefile); | |||
| fos.write(data); | |||
| } catch (Exception e) { | |||
| LOGGER.error(e.getMessage(), e); | |||
| } finally { | |||
| try { | |||
| fos.close(); | |||
| } catch (Exception e) { | |||
| LOGGER.error(e.getMessage(), e); | |||
| } | |||
| } | |||
| return imageCachePath + "/" + today + "/" + fileName;*/ | |||
| } | |||
| private String styleName(CellStyle style) { | |||
| if (style == null) { | |||
| return ""; | |||
| } | |||
| return String.format("style_%02x_%s font_%s_%s", style.getIndex(), cssRandom, | |||
| style.getFontIndex(), cssRandom); | |||
| } | |||
| } | |||
| package cn.afterturn.easypoi.excel.html; | |||
| import java.text.SimpleDateFormat; | |||
| import java.util.Date; | |||
| import java.util.Formatter; | |||
| import java.util.HashMap; | |||
| import java.util.Iterator; | |||
| import java.util.Map; | |||
| import org.apache.commons.lang3.StringUtils; | |||
| import org.apache.poi.hssf.usermodel.HSSFSheet; | |||
| import org.apache.poi.hssf.usermodel.HSSFWorkbook; | |||
| import org.apache.poi.ss.usermodel.Cell; | |||
| import org.apache.poi.ss.usermodel.CellStyle; | |||
| import org.apache.poi.ss.usermodel.PictureData; | |||
| import org.apache.poi.ss.usermodel.Row; | |||
| import org.apache.poi.ss.usermodel.Sheet; | |||
| import org.apache.poi.ss.usermodel.Workbook; | |||
| import org.apache.poi.xssf.usermodel.XSSFSheet; | |||
| import org.apache.poi.xssf.usermodel.XSSFWorkbook; | |||
| import org.slf4j.Logger; | |||
| import org.slf4j.LoggerFactory; | |||
| import sun.misc.BASE64Encoder; | |||
| import cn.afterturn.easypoi.excel.entity.ExcelToHtmlParams; | |||
| import cn.afterturn.easypoi.excel.html.helper.CellValueHelper; | |||
| import cn.afterturn.easypoi.excel.html.helper.MergedRegionHelper; | |||
| import cn.afterturn.easypoi.excel.html.helper.StylerHelper; | |||
| import cn.afterturn.easypoi.util.PoiPublicUtil; | |||
| /** | |||
| * Excel转换成Html 服务 | |||
| * @author JueYue | |||
| * 2015年5月10日 上午11:41:15 | |||
| */ | |||
| public class ExcelToHtmlService { | |||
| private static final Logger LOGGER = LoggerFactory | |||
| .getLogger(ExcelToHtmlService.class); | |||
| private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy_MM_dd"); | |||
| private String today; | |||
| private Workbook wb; | |||
| private int sheetNum; | |||
| private int cssRandom; | |||
| /*是不是完成界面*/ | |||
| private boolean completeHTML; | |||
| private Formatter out; | |||
| /*已经完成范围处理*/ | |||
| private boolean gotBounds; | |||
| private int firstColumn; | |||
| private int endColumn; | |||
| private String imageCachePath; | |||
| private static final String COL_HEAD_CLASS = "colHeader"; | |||
| //private static final String ROW_HEAD_CLASS = "rowHeader"; | |||
| private static final String DEFAULTS_CLASS = "excelDefaults"; | |||
| //图片缓存 | |||
| private Map<String, PictureData> pictures = new HashMap<String, PictureData>(); | |||
| public ExcelToHtmlService(ExcelToHtmlParams params) { | |||
| this.wb = params.getWb(); | |||
| this.completeHTML = params.isCompleteHTML(); | |||
| this.sheetNum = params.getSheetNum(); | |||
| cssRandom = (int) Math.ceil(Math.random() * 1000); | |||
| this.imageCachePath = params.getPath(); | |||
| today = new SimpleDateFormat("yyyy_MM_dd").format(new Date()); | |||
| } | |||
| public String printPage() { | |||
| try { | |||
| ensureOut(); | |||
| if (completeHTML) { | |||
| out.format("<!DOCTYPE HTML>%n"); | |||
| out.format("<html>%n"); | |||
| out.format( | |||
| "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">%n"); | |||
| out.format("<head>%n"); | |||
| } | |||
| if (StringUtils.isNotEmpty(imageCachePath)) { | |||
| getPictures(); | |||
| } | |||
| new StylerHelper(wb, out, sheetNum, cssRandom); | |||
| if (completeHTML) { | |||
| out.format("</head>%n"); | |||
| out.format("<body>%n"); | |||
| } | |||
| print(); | |||
| if (completeHTML) { | |||
| out.format("</body>%n"); | |||
| out.format("</html>%n"); | |||
| } | |||
| return out.toString(); | |||
| } catch (Exception e) { | |||
| LOGGER.error(e.getMessage(), e); | |||
| } finally { | |||
| if (out != null) { | |||
| out.close(); | |||
| } | |||
| } | |||
| return null; | |||
| } | |||
| /** | |||
| * 获取Sheet缓存的图片 | |||
| */ | |||
| private void getPictures() { | |||
| if (wb instanceof XSSFWorkbook) { | |||
| pictures = PoiPublicUtil.getSheetPictrues07((XSSFSheet) wb.getSheetAt(sheetNum), | |||
| (XSSFWorkbook) wb); | |||
| } else { | |||
| pictures = PoiPublicUtil.getSheetPictrues03((HSSFSheet) wb.getSheetAt(sheetNum), | |||
| (HSSFWorkbook) wb); | |||
| } | |||
| } | |||
| private void print() { | |||
| printSheets(); | |||
| } | |||
| private void ensureOut() { | |||
| if (out == null) { | |||
| out = new Formatter(new StringBuilder()); | |||
| } | |||
| } | |||
| private void printSheets() { | |||
| Sheet sheet = wb.getSheetAt(sheetNum); | |||
| printSheet(sheet); | |||
| } | |||
| private void printSheet(Sheet sheet) { | |||
| out.format("<table class='%s' width='%s'>%n", DEFAULTS_CLASS, getTableWidth(sheet)); | |||
| printCols(sheet); | |||
| printSheetContent(sheet); | |||
| out.format("</table>%n"); | |||
| } | |||
| private void printCols(Sheet sheet) { | |||
| //out.format("<col/>%n"); | |||
| ensureColumnBounds(sheet); | |||
| for (int i = firstColumn; i < endColumn; i++) { | |||
| out.format("<col style='width:%spx;' />%n", sheet.getColumnWidth(i) / 32); | |||
| } | |||
| } | |||
| private int getTableWidth(Sheet sheet) { | |||
| ensureColumnBounds(sheet); | |||
| int width = 0; | |||
| for (int i = firstColumn; i < endColumn; i++) { | |||
| width = width + (sheet.getColumnWidth(i) / 32); | |||
| } | |||
| return width; | |||
| } | |||
| private void ensureColumnBounds(Sheet sheet) { | |||
| if (gotBounds) { | |||
| return; | |||
| } | |||
| Iterator<Row> iter = sheet.rowIterator(); | |||
| firstColumn = (iter.hasNext() ? Integer.MAX_VALUE : 0); | |||
| endColumn = 0; | |||
| while (iter.hasNext()) { | |||
| Row row = iter.next(); | |||
| short firstCell = row.getFirstCellNum(); | |||
| if (firstCell >= 0) { | |||
| firstColumn = Math.min(firstColumn, firstCell); | |||
| endColumn = Math.max(endColumn, row.getLastCellNum()); | |||
| } | |||
| } | |||
| gotBounds = true; | |||
| } | |||
| @SuppressWarnings("unused") | |||
| /**本来是用来生成 A,B 那个列名称的**/ | |||
| private void printColumnHeads(Sheet sheet) { | |||
| out.format("<thead>%n"); | |||
| out.format(" <tr class=%s>%n", COL_HEAD_CLASS); | |||
| out.format(" <th class=%s>◊</th>%n", COL_HEAD_CLASS); | |||
| StringBuilder colName = new StringBuilder(); | |||
| for (int i = firstColumn; i < endColumn; i++) { | |||
| colName.setLength(0); | |||
| int cnum = i; | |||
| do { | |||
| colName.insert(0, (char) ('A' + cnum % 26)); | |||
| cnum /= 26; | |||
| } while (cnum > 0); | |||
| out.format(" <th class=%s>%s</th>%n", COL_HEAD_CLASS, colName); | |||
| } | |||
| out.format(" </tr>%n"); | |||
| out.format("</thead>%n"); | |||
| } | |||
| private void printSheetContent(Sheet sheet) { | |||
| //printColumnHeads(sheet); | |||
| MergedRegionHelper mergedRegionHelper = new MergedRegionHelper(sheet); | |||
| CellValueHelper cellValueHelper = new CellValueHelper(wb, cssRandom); | |||
| out.format("<tbody>%n"); | |||
| Iterator<Row> rows = sheet.rowIterator(); | |||
| int rowIndex = 1; | |||
| while (rows.hasNext()) { | |||
| Row row = rows.next(); | |||
| out.format(" <tr style='height:%spx;'>%n", row.getHeight() / 15); | |||
| //out.format(" <td class='%s'>%d</td>%n", ROW_HEAD_CLASS, row.getRowNum() + 1); | |||
| for (int i = firstColumn; i < endColumn; i++) { | |||
| if (mergedRegionHelper.isNeedCreate(rowIndex, i)) { | |||
| String content = " "; | |||
| CellStyle style = null; | |||
| if (i >= row.getFirstCellNum() && i < row.getLastCellNum()) { | |||
| Cell cell = row.getCell(i); | |||
| if (cell != null) { | |||
| style = cell.getCellStyle(); | |||
| content = cellValueHelper.getHtmlValue(cell); | |||
| } | |||
| } | |||
| if (pictures.containsKey((rowIndex - 1) + "_" + i)) { | |||
| content = "<img src='data:image/"+PoiPublicUtil.getFileExtendName(pictures.get((rowIndex - 1) + "_" + i).getData()) | |||
| +";base64," + getImageSrc(pictures.get((rowIndex - 1) + "_" + i)) | |||
| + "' style='max-width: " | |||
| + getImageMaxWidth( | |||
| mergedRegionHelper.getRowAndColSpan(rowIndex, i), i, sheet) | |||
| + "px;' />"; | |||
| } | |||
| if (mergedRegionHelper.isMergedRegion(rowIndex, i)) { | |||
| Integer[] rowAndColSpan = mergedRegionHelper.getRowAndColSpan(rowIndex, i); | |||
| out.format(" <td rowspan='%s' colspan='%s' class='%s' >%s</td>%n", | |||
| rowAndColSpan[0], rowAndColSpan[1], styleName(style), content); | |||
| } else { | |||
| out.format(" <td class='%s'>%s</td>%n", styleName(style), content); | |||
| } | |||
| } | |||
| } | |||
| out.format(" </tr>%n"); | |||
| rowIndex++; | |||
| } | |||
| out.format("</tbody>%n"); | |||
| } | |||
| /** | |||
| * 获取图片最大宽度 | |||
| * @param colIndex | |||
| * @param sheet | |||
| * @param rowAndColSpan | |||
| * @return | |||
| */ | |||
| private int getImageMaxWidth(Integer[] rowAndColSpan, int colIndex, Sheet sheet) { | |||
| if (rowAndColSpan == null) { | |||
| return sheet.getColumnWidth(colIndex) / 32; | |||
| } | |||
| int maxWidth = 0; | |||
| for (int i = 0; i < rowAndColSpan[1]; i++) { | |||
| maxWidth += sheet.getColumnWidth(colIndex + i) / 32; | |||
| } | |||
| return maxWidth; | |||
| } | |||
| /** | |||
| * 获取图片路径 | |||
| * @param pictureData | |||
| * @return | |||
| */ | |||
| private String getImageSrc(PictureData pictureData) { | |||
| if (pictureData == null) { | |||
| return ""; | |||
| } | |||
| byte[] data = pictureData.getData(); | |||
| //直接输出到HTML使用BASE64Encoder | |||
| // 加密 | |||
| BASE64Encoder encoder = new BASE64Encoder(); | |||
| return encoder.encode(data); | |||
| /*String fileName = "pic" + Math.round(Math.random() * 100000000000L); | |||
| fileName += "." + PoiPublicUtil.getFileExtendName(data); | |||
| if (!imageCachePath.startsWith("/") && !imageCachePath.contains(":")) { | |||
| imageCachePath = PoiPublicUtil.getWebRootPath(imageCachePath); | |||
| } | |||
| File savefile = new File(imageCachePath + "/" + today); | |||
| if (!savefile.exists()) { | |||
| savefile.mkdirs(); | |||
| } | |||
| savefile = new File(imageCachePath + "/" + today + "/" + fileName); | |||
| FileOutputStream fos = null; | |||
| try { | |||
| fos = new FileOutputStream(savefile); | |||
| fos.write(data); | |||
| } catch (Exception e) { | |||
| LOGGER.error(e.getMessage(), e); | |||
| } finally { | |||
| try { | |||
| fos.close(); | |||
| } catch (Exception e) { | |||
| LOGGER.error(e.getMessage(), e); | |||
| } | |||
| } | |||
| return imageCachePath + "/" + today + "/" + fileName;*/ | |||
| } | |||
| private String styleName(CellStyle style) { | |||
| if (style == null) { | |||
| return ""; | |||
| } | |||
| return String.format("style_%02x_%s font_%s_%s", style.getIndex(), cssRandom, | |||
| style.getFontIndex(), cssRandom); | |||
| } | |||
| } | |||
| @@ -1,274 +1,274 @@ | |||
| package cn.afterturn.easypoi.excel.html; | |||
| import java.util.Map; | |||
| import java.util.List; | |||
| import org.jsoup.Jsoup; | |||
| import org.slf4j.Logger; | |||
| import java.util.HashMap; | |||
| import java.util.LinkedList; | |||
| import org.slf4j.LoggerFactory; | |||
| import cn.afterturn.easypoi.excel.export.styler.ExcelExportStylerDefaultImpl; | |||
| import cn.afterturn.easypoi.excel.html.css.CssParseServer; | |||
| import cn.afterturn.easypoi.excel.html.css.ICssConvertToExcel; | |||
| import cn.afterturn.easypoi.excel.html.css.impl.AlignCssConvertImpl; | |||
| import cn.afterturn.easypoi.excel.html.css.impl.BackgroundCssConvertImpl; | |||
| import cn.afterturn.easypoi.excel.html.css.impl.BorderCssConverImpl; | |||
| import cn.afterturn.easypoi.excel.html.css.impl.HeightCssConverImpl; | |||
| import cn.afterturn.easypoi.excel.html.css.impl.TextCssConvertImpl; | |||
| import cn.afterturn.easypoi.excel.html.css.impl.WidthCssConverImpl; | |||
| import cn.afterturn.easypoi.excel.html.entity.ExcelCssConstant; | |||
| import cn.afterturn.easypoi.excel.html.entity.HtmlCssConstant; | |||
| import cn.afterturn.easypoi.excel.html.entity.style.CellStyleEntity; | |||
| import org.jsoup.nodes.Element; | |||
| import org.jsoup.select.Elements; | |||
| import javax.management.RuntimeErrorException; | |||
| import org.apache.commons.lang3.StringUtils; | |||
| import org.apache.poi.ss.usermodel.Cell; | |||
| import org.apache.poi.ss.usermodel.Sheet; | |||
| import org.apache.poi.ss.usermodel.Workbook; | |||
| import org.apache.poi.ss.usermodel.CellStyle; | |||
| import org.apache.poi.ss.usermodel.Row; | |||
| import org.apache.poi.ss.util.CellRangeAddress; | |||
| /** | |||
| * 读取Table数据生成Excel | |||
| * @author JueYue | |||
| * 2017年3月19日 | |||
| */ | |||
| public class HtmlToExcelServer { | |||
| private final Logger LOGGER = LoggerFactory | |||
| .getLogger(HtmlToExcelServer.class); | |||
| //样式 | |||
| private static final List<ICssConvertToExcel> STYLE_APPLIERS = new LinkedList<ICssConvertToExcel>(); | |||
| { | |||
| STYLE_APPLIERS.add(new AlignCssConvertImpl()); | |||
| STYLE_APPLIERS.add(new BackgroundCssConvertImpl()); | |||
| STYLE_APPLIERS.add(new BorderCssConverImpl()); | |||
| STYLE_APPLIERS.add(new TextCssConvertImpl()); | |||
| } | |||
| //Cell 高宽 | |||
| private static final List<ICssConvertToExcel> SHEET_APPLIERS = new LinkedList<ICssConvertToExcel>(); | |||
| { | |||
| SHEET_APPLIERS.add(new WidthCssConverImpl()); | |||
| SHEET_APPLIERS.add(new HeightCssConverImpl()); | |||
| } | |||
| private Sheet sheet; | |||
| private Map<String, Object> cellsOccupied = new HashMap<String, Object>(); | |||
| private Map<String, CellStyle> cellStyles = new HashMap<String, CellStyle>(); | |||
| private CellStyle defaultCellStyle; | |||
| private int maxRow = 0; | |||
| private CssParseServer cssParse = new CssParseServer(); | |||
| // -- | |||
| // private methods | |||
| private void processTable(Element table) { | |||
| int rowIndex = 0; | |||
| if (maxRow > 0) { | |||
| // blank row | |||
| maxRow += 2; | |||
| rowIndex = maxRow; | |||
| } | |||
| LOGGER.debug("Interate Table Rows."); | |||
| String freezeCol = null; | |||
| int freezeColIndex = -1; | |||
| for (Element row : table.select("tr")) { | |||
| LOGGER.debug("Parse Table Row [{}]. Row Index [{}].", row, rowIndex); | |||
| String freezeRow = row.attr(ExcelCssConstant.FREEZE_ROW); | |||
| if ("true".equals(freezeRow)) { | |||
| sheet.createFreezePane(0, rowIndex + 1, 0, rowIndex + 1); | |||
| } | |||
| int colIndex = 0; | |||
| LOGGER.debug("Interate Cols."); | |||
| for (Element td : row.select("td, th")) { | |||
| freezeCol = td.attr(ExcelCssConstant.FREEZE_COL); | |||
| if ("true".equals(freezeCol)) { | |||
| if (colIndex > freezeColIndex) { | |||
| freezeColIndex = colIndex; | |||
| } | |||
| } | |||
| // skip occupied cell | |||
| while (cellsOccupied.get(rowIndex + "_" + colIndex) != null) { | |||
| LOGGER.debug("Cell [{}][{}] Has Been Occupied, Skip.", rowIndex, colIndex); | |||
| ++colIndex; | |||
| } | |||
| LOGGER.debug("Parse Col [{}], Col Index [{}].", td, colIndex); | |||
| int rowSpan = 0; | |||
| String strRowSpan = td.attr("rowspan"); | |||
| if (StringUtils.isNotBlank(strRowSpan) && StringUtils.isNumeric(strRowSpan)) { | |||
| LOGGER.debug("Found Row Span [{}].", strRowSpan); | |||
| rowSpan = Integer.parseInt(strRowSpan); | |||
| } | |||
| int colSpan = 0; | |||
| String strColSpan = td.attr("colspan"); | |||
| if (StringUtils.isNotBlank(strColSpan) && StringUtils.isNumeric(strColSpan)) { | |||
| LOGGER.debug("Found Col Span [{}].", strColSpan); | |||
| colSpan = Integer.parseInt(strColSpan); | |||
| } | |||
| // col span & row span | |||
| if (colSpan > 1 && rowSpan > 1) { | |||
| spanRowAndCol(td, rowIndex, colIndex, rowSpan, colSpan); | |||
| colIndex += colSpan; | |||
| } | |||
| // col span only | |||
| else if (colSpan > 1) { | |||
| spanCol(td, rowIndex, colIndex, colSpan); | |||
| colIndex += colSpan; | |||
| } | |||
| // row span only | |||
| else if (rowSpan > 1) { | |||
| spanRow(td, rowIndex, colIndex, rowSpan); | |||
| ++colIndex; | |||
| } | |||
| // no span | |||
| else { | |||
| createCell(td, getOrCreateRow(rowIndex), colIndex).setCellValue(td.text()); | |||
| ++colIndex; | |||
| } | |||
| } | |||
| ++rowIndex; | |||
| } | |||
| if (freezeColIndex != -1) { | |||
| sheet.createFreezePane(freezeColIndex + 1, 0, freezeColIndex + 1, 0); | |||
| } | |||
| } | |||
| public Workbook createSheet(String html, Workbook workbook) { | |||
| Elements els = Jsoup.parseBodyFragment(html).select("table"); | |||
| Map<String, Sheet> sheets = new HashMap<String, Sheet>(); | |||
| Map<String, Integer> maxrowMap = new HashMap<String, Integer>(); | |||
| for (Element table : els) { | |||
| String sheetName = table.attr(ExcelCssConstant.SHEET_NAME); | |||
| if (StringUtils.isBlank(sheetName)) { | |||
| LOGGER.error("table必须存在name属性!"); | |||
| throw new RuntimeErrorException(null, "table必须存在name属性"); | |||
| } | |||
| if (sheets.containsKey(sheetName)) { | |||
| maxRow = maxrowMap.get(sheetName); | |||
| //cellStyles = csStyleMap.get(sheetName); | |||
| //cellsOccupied = cellsOccupiedMap.get(sheetName); | |||
| sheet = sheets.get(sheetName); | |||
| } else { | |||
| maxRow = 0; | |||
| cellStyles.clear(); | |||
| cellsOccupied.clear(); | |||
| sheet = workbook.createSheet(sheetName); | |||
| } | |||
| //生成一个默认样式 | |||
| defaultCellStyle = new ExcelExportStylerDefaultImpl(workbook).stringNoneStyle(workbook, | |||
| false); | |||
| processTable(table); | |||
| maxrowMap.put(sheetName, maxRow); | |||
| sheets.put(sheetName, sheet); | |||
| } | |||
| return workbook; | |||
| } | |||
| private void spanRow(Element td, int rowIndex, int colIndex, int rowSpan) { | |||
| LOGGER.debug("Span Row , From Row [{}], Span [{}].", rowIndex, rowSpan); | |||
| mergeRegion(rowIndex, rowIndex + rowSpan - 1, colIndex, colIndex); | |||
| for (int i = 0; i < rowSpan; ++i) { | |||
| Row row = getOrCreateRow(rowIndex + i); | |||
| createCell(td, row, colIndex); | |||
| cellsOccupied.put((rowIndex + i) + "_" + colIndex, true); | |||
| } | |||
| getOrCreateRow(rowIndex).getCell(colIndex).setCellValue(td.text()); | |||
| } | |||
| private void spanCol(Element td, int rowIndex, int colIndex, int colSpan) { | |||
| LOGGER.debug("Span Col, From Col [{}], Span [{}].", colIndex, colSpan); | |||
| mergeRegion(rowIndex, rowIndex, colIndex, colIndex + colSpan - 1); | |||
| Row row = getOrCreateRow(rowIndex); | |||
| for (int i = 0; i < colSpan; ++i) { | |||
| createCell(td, row, colIndex + i); | |||
| } | |||
| row.getCell(colIndex).setCellValue(td.text()); | |||
| } | |||
| private void spanRowAndCol(Element td, int rowIndex, int colIndex, int rowSpan, int colSpan) { | |||
| LOGGER.debug("Span Row And Col, From Row [{}], Span [{}].", rowIndex, rowSpan); | |||
| LOGGER.debug("From Col [{}], Span [{}].", colIndex, colSpan); | |||
| mergeRegion(rowIndex, rowIndex + rowSpan - 1, colIndex, colIndex + colSpan - 1); | |||
| for (int i = 0; i < rowSpan; ++i) { | |||
| Row row = getOrCreateRow(rowIndex + i); | |||
| for (int j = 0; j < colSpan; ++j) { | |||
| createCell(td, row, colIndex + j); | |||
| cellsOccupied.put((rowIndex + i) + "_" + (colIndex + j), true); | |||
| } | |||
| } | |||
| getOrCreateRow(rowIndex).getCell(colIndex).setCellValue(td.text()); | |||
| } | |||
| private Cell createCell(Element td, Row row, int colIndex) { | |||
| Cell cell = row.getCell(colIndex); | |||
| if (cell == null) { | |||
| LOGGER.debug("Create Cell [{}][{}].", row.getRowNum(), colIndex); | |||
| cell = row.createCell(colIndex); | |||
| } | |||
| return applyStyle(td, cell); | |||
| } | |||
| private Cell applyStyle(Element td, Cell cell) { | |||
| String style = td.attr(HtmlCssConstant.STYLE); | |||
| CellStyle cellStyle = null; | |||
| if (StringUtils.isNotBlank(style)) { | |||
| CellStyleEntity styleEntity = cssParse.parseStyle(style.trim()); | |||
| cellStyle = cellStyles.get(styleEntity.toString()); | |||
| if (cellStyle == null) { | |||
| LOGGER.debug("No Cell Style Found In Cache, Parse New Style."); | |||
| cellStyle = cell.getRow().getSheet().getWorkbook().createCellStyle(); | |||
| cellStyle.cloneStyleFrom(defaultCellStyle); | |||
| for (ICssConvertToExcel cssConvert : STYLE_APPLIERS) { | |||
| cssConvert.convertToExcel(cell, cellStyle, styleEntity); | |||
| } | |||
| cellStyles.put(styleEntity.toString(), cellStyle); | |||
| } | |||
| for (ICssConvertToExcel cssConvert : SHEET_APPLIERS) { | |||
| cssConvert.convertToExcel(cell, cellStyle, styleEntity); | |||
| } | |||
| if (cellStyles.size() >= 4000) { | |||
| LOGGER.info( | |||
| "Custom Cell Style Exceeds 4000, Could Not Create New Style, Use Default Style."); | |||
| cellStyle = defaultCellStyle; | |||
| } | |||
| } else { | |||
| LOGGER.debug("Style is null ,Use Default Cell Style."); | |||
| cellStyle = defaultCellStyle; | |||
| } | |||
| cell.setCellStyle(cellStyle); | |||
| return cell; | |||
| } | |||
| private Row getOrCreateRow(int rowIndex) { | |||
| Row row = sheet.getRow(rowIndex); | |||
| if (row == null) { | |||
| LOGGER.debug("Create New Row [{}].", rowIndex); | |||
| row = sheet.createRow(rowIndex); | |||
| if (rowIndex > maxRow) { | |||
| maxRow = rowIndex; | |||
| } | |||
| } | |||
| return row; | |||
| } | |||
| private void mergeRegion(int firstRow, int lastRow, int firstCol, int lastCol) { | |||
| LOGGER.debug("Merge Region, From Row [{}], To [{}].", firstRow, lastRow); | |||
| LOGGER.debug("From Col [{}], To [{}].", firstCol, lastCol); | |||
| sheet.addMergedRegion(new CellRangeAddress(firstRow, lastRow, firstCol, lastCol)); | |||
| } | |||
| } | |||
| package cn.afterturn.easypoi.excel.html; | |||
| import java.util.Map; | |||
| import java.util.List; | |||
| import org.jsoup.Jsoup; | |||
| import org.slf4j.Logger; | |||
| import java.util.HashMap; | |||
| import java.util.LinkedList; | |||
| import org.slf4j.LoggerFactory; | |||
| import cn.afterturn.easypoi.excel.export.styler.ExcelExportStylerDefaultImpl; | |||
| import cn.afterturn.easypoi.excel.html.css.CssParseService; | |||
| import cn.afterturn.easypoi.excel.html.css.ICssConvertToExcel; | |||
| import cn.afterturn.easypoi.excel.html.css.impl.AlignCssConvertImpl; | |||
| import cn.afterturn.easypoi.excel.html.css.impl.BackgroundCssConvertImpl; | |||
| import cn.afterturn.easypoi.excel.html.css.impl.BorderCssConverImpl; | |||
| import cn.afterturn.easypoi.excel.html.css.impl.HeightCssConverImpl; | |||
| import cn.afterturn.easypoi.excel.html.css.impl.TextCssConvertImpl; | |||
| import cn.afterturn.easypoi.excel.html.css.impl.WidthCssConverImpl; | |||
| import cn.afterturn.easypoi.excel.html.entity.ExcelCssConstant; | |||
| import cn.afterturn.easypoi.excel.html.entity.HtmlCssConstant; | |||
| import cn.afterturn.easypoi.excel.html.entity.style.CellStyleEntity; | |||
| import org.jsoup.nodes.Element; | |||
| import org.jsoup.select.Elements; | |||
| import javax.management.RuntimeErrorException; | |||
| import org.apache.commons.lang3.StringUtils; | |||
| import org.apache.poi.ss.usermodel.Cell; | |||
| import org.apache.poi.ss.usermodel.Sheet; | |||
| import org.apache.poi.ss.usermodel.Workbook; | |||
| import org.apache.poi.ss.usermodel.CellStyle; | |||
| import org.apache.poi.ss.usermodel.Row; | |||
| import org.apache.poi.ss.util.CellRangeAddress; | |||
| /** | |||
| * 读取Table数据生成Excel | |||
| * @author JueYue | |||
| * 2017年3月19日 | |||
| */ | |||
| public class HtmlToExcelService { | |||
| private final Logger LOGGER = LoggerFactory | |||
| .getLogger(HtmlToExcelService.class); | |||
| //样式 | |||
| private static final List<ICssConvertToExcel> STYLE_APPLIERS = new LinkedList<ICssConvertToExcel>(); | |||
| { | |||
| STYLE_APPLIERS.add(new AlignCssConvertImpl()); | |||
| STYLE_APPLIERS.add(new BackgroundCssConvertImpl()); | |||
| STYLE_APPLIERS.add(new BorderCssConverImpl()); | |||
| STYLE_APPLIERS.add(new TextCssConvertImpl()); | |||
| } | |||
| //Cell 高宽 | |||
| private static final List<ICssConvertToExcel> SHEET_APPLIERS = new LinkedList<ICssConvertToExcel>(); | |||
| { | |||
| SHEET_APPLIERS.add(new WidthCssConverImpl()); | |||
| SHEET_APPLIERS.add(new HeightCssConverImpl()); | |||
| } | |||
| private Sheet sheet; | |||
| private Map<String, Object> cellsOccupied = new HashMap<String, Object>(); | |||
| private Map<String, CellStyle> cellStyles = new HashMap<String, CellStyle>(); | |||
| private CellStyle defaultCellStyle; | |||
| private int maxRow = 0; | |||
| private CssParseService cssParse = new CssParseService(); | |||
| // -- | |||
| // private methods | |||
| private void processTable(Element table) { | |||
| int rowIndex = 0; | |||
| if (maxRow > 0) { | |||
| // blank row | |||
| maxRow += 2; | |||
| rowIndex = maxRow; | |||
| } | |||
| LOGGER.debug("Interate Table Rows."); | |||
| String freezeCol = null; | |||
| int freezeColIndex = -1; | |||
| for (Element row : table.select("tr")) { | |||
| LOGGER.debug("Parse Table Row [{}]. Row Index [{}].", row, rowIndex); | |||
| String freezeRow = row.attr(ExcelCssConstant.FREEZE_ROW); | |||
| if ("true".equals(freezeRow)) { | |||
| sheet.createFreezePane(0, rowIndex + 1, 0, rowIndex + 1); | |||
| } | |||
| int colIndex = 0; | |||
| LOGGER.debug("Interate Cols."); | |||
| for (Element td : row.select("td, th")) { | |||
| freezeCol = td.attr(ExcelCssConstant.FREEZE_COL); | |||
| if ("true".equals(freezeCol)) { | |||
| if (colIndex > freezeColIndex) { | |||
| freezeColIndex = colIndex; | |||
| } | |||
| } | |||
| // skip occupied cell | |||
| while (cellsOccupied.get(rowIndex + "_" + colIndex) != null) { | |||
| LOGGER.debug("Cell [{}][{}] Has Been Occupied, Skip.", rowIndex, colIndex); | |||
| ++colIndex; | |||
| } | |||
| LOGGER.debug("Parse Col [{}], Col Index [{}].", td, colIndex); | |||
| int rowSpan = 0; | |||
| String strRowSpan = td.attr("rowspan"); | |||
| if (StringUtils.isNotBlank(strRowSpan) && StringUtils.isNumeric(strRowSpan)) { | |||
| LOGGER.debug("Found Row Span [{}].", strRowSpan); | |||
| rowSpan = Integer.parseInt(strRowSpan); | |||
| } | |||
| int colSpan = 0; | |||
| String strColSpan = td.attr("colspan"); | |||
| if (StringUtils.isNotBlank(strColSpan) && StringUtils.isNumeric(strColSpan)) { | |||
| LOGGER.debug("Found Col Span [{}].", strColSpan); | |||
| colSpan = Integer.parseInt(strColSpan); | |||
| } | |||
| // col span & row span | |||
| if (colSpan > 1 && rowSpan > 1) { | |||
| spanRowAndCol(td, rowIndex, colIndex, rowSpan, colSpan); | |||
| colIndex += colSpan; | |||
| } | |||
| // col span only | |||
| else if (colSpan > 1) { | |||
| spanCol(td, rowIndex, colIndex, colSpan); | |||
| colIndex += colSpan; | |||
| } | |||
| // row span only | |||
| else if (rowSpan > 1) { | |||
| spanRow(td, rowIndex, colIndex, rowSpan); | |||
| ++colIndex; | |||
| } | |||
| // no span | |||
| else { | |||
| createCell(td, getOrCreateRow(rowIndex), colIndex).setCellValue(td.text()); | |||
| ++colIndex; | |||
| } | |||
| } | |||
| ++rowIndex; | |||
| } | |||
| if (freezeColIndex != -1) { | |||
| sheet.createFreezePane(freezeColIndex + 1, 0, freezeColIndex + 1, 0); | |||
| } | |||
| } | |||
| public Workbook createSheet(String html, Workbook workbook) { | |||
| Elements els = Jsoup.parseBodyFragment(html).select("table"); | |||
| Map<String, Sheet> sheets = new HashMap<String, Sheet>(); | |||
| Map<String, Integer> maxrowMap = new HashMap<String, Integer>(); | |||
| for (Element table : els) { | |||
| String sheetName = table.attr(ExcelCssConstant.SHEET_NAME); | |||
| if (StringUtils.isBlank(sheetName)) { | |||
| LOGGER.error("table必须存在name属性!"); | |||
| throw new RuntimeErrorException(null, "table必须存在name属性"); | |||
| } | |||
| if (sheets.containsKey(sheetName)) { | |||
| maxRow = maxrowMap.get(sheetName); | |||
| //cellStyles = csStyleMap.get(sheetName); | |||
| //cellsOccupied = cellsOccupiedMap.get(sheetName); | |||
| sheet = sheets.get(sheetName); | |||
| } else { | |||
| maxRow = 0; | |||
| cellStyles.clear(); | |||
| cellsOccupied.clear(); | |||
| sheet = workbook.createSheet(sheetName); | |||
| } | |||
| //生成一个默认样式 | |||
| defaultCellStyle = new ExcelExportStylerDefaultImpl(workbook).stringNoneStyle(workbook, | |||
| false); | |||
| processTable(table); | |||
| maxrowMap.put(sheetName, maxRow); | |||
| sheets.put(sheetName, sheet); | |||
| } | |||
| return workbook; | |||
| } | |||
| private void spanRow(Element td, int rowIndex, int colIndex, int rowSpan) { | |||
| LOGGER.debug("Span Row , From Row [{}], Span [{}].", rowIndex, rowSpan); | |||
| mergeRegion(rowIndex, rowIndex + rowSpan - 1, colIndex, colIndex); | |||
| for (int i = 0; i < rowSpan; ++i) { | |||
| Row row = getOrCreateRow(rowIndex + i); | |||
| createCell(td, row, colIndex); | |||
| cellsOccupied.put((rowIndex + i) + "_" + colIndex, true); | |||
| } | |||
| getOrCreateRow(rowIndex).getCell(colIndex).setCellValue(td.text()); | |||
| } | |||
| private void spanCol(Element td, int rowIndex, int colIndex, int colSpan) { | |||
| LOGGER.debug("Span Col, From Col [{}], Span [{}].", colIndex, colSpan); | |||
| mergeRegion(rowIndex, rowIndex, colIndex, colIndex + colSpan - 1); | |||
| Row row = getOrCreateRow(rowIndex); | |||
| for (int i = 0; i < colSpan; ++i) { | |||
| createCell(td, row, colIndex + i); | |||
| } | |||
| row.getCell(colIndex).setCellValue(td.text()); | |||
| } | |||
| private void spanRowAndCol(Element td, int rowIndex, int colIndex, int rowSpan, int colSpan) { | |||
| LOGGER.debug("Span Row And Col, From Row [{}], Span [{}].", rowIndex, rowSpan); | |||
| LOGGER.debug("From Col [{}], Span [{}].", colIndex, colSpan); | |||
| mergeRegion(rowIndex, rowIndex + rowSpan - 1, colIndex, colIndex + colSpan - 1); | |||
| for (int i = 0; i < rowSpan; ++i) { | |||
| Row row = getOrCreateRow(rowIndex + i); | |||
| for (int j = 0; j < colSpan; ++j) { | |||
| createCell(td, row, colIndex + j); | |||
| cellsOccupied.put((rowIndex + i) + "_" + (colIndex + j), true); | |||
| } | |||
| } | |||
| getOrCreateRow(rowIndex).getCell(colIndex).setCellValue(td.text()); | |||
| } | |||
| private Cell createCell(Element td, Row row, int colIndex) { | |||
| Cell cell = row.getCell(colIndex); | |||
| if (cell == null) { | |||
| LOGGER.debug("Create Cell [{}][{}].", row.getRowNum(), colIndex); | |||
| cell = row.createCell(colIndex); | |||
| } | |||
| return applyStyle(td, cell); | |||
| } | |||
| private Cell applyStyle(Element td, Cell cell) { | |||
| String style = td.attr(HtmlCssConstant.STYLE); | |||
| CellStyle cellStyle = null; | |||
| if (StringUtils.isNotBlank(style)) { | |||
| CellStyleEntity styleEntity = cssParse.parseStyle(style.trim()); | |||
| cellStyle = cellStyles.get(styleEntity.toString()); | |||
| if (cellStyle == null) { | |||
| LOGGER.debug("No Cell Style Found In Cache, Parse New Style."); | |||
| cellStyle = cell.getRow().getSheet().getWorkbook().createCellStyle(); | |||
| cellStyle.cloneStyleFrom(defaultCellStyle); | |||
| for (ICssConvertToExcel cssConvert : STYLE_APPLIERS) { | |||
| cssConvert.convertToExcel(cell, cellStyle, styleEntity); | |||
| } | |||
| cellStyles.put(styleEntity.toString(), cellStyle); | |||
| } | |||
| for (ICssConvertToExcel cssConvert : SHEET_APPLIERS) { | |||
| cssConvert.convertToExcel(cell, cellStyle, styleEntity); | |||
| } | |||
| if (cellStyles.size() >= 4000) { | |||
| LOGGER.info( | |||
| "Custom Cell Style Exceeds 4000, Could Not Create New Style, Use Default Style."); | |||
| cellStyle = defaultCellStyle; | |||
| } | |||
| } else { | |||
| LOGGER.debug("Style is null ,Use Default Cell Style."); | |||
| cellStyle = defaultCellStyle; | |||
| } | |||
| cell.setCellStyle(cellStyle); | |||
| return cell; | |||
| } | |||
| private Row getOrCreateRow(int rowIndex) { | |||
| Row row = sheet.getRow(rowIndex); | |||
| if (row == null) { | |||
| LOGGER.debug("Create New Row [{}].", rowIndex); | |||
| row = sheet.createRow(rowIndex); | |||
| if (rowIndex > maxRow) { | |||
| maxRow = rowIndex; | |||
| } | |||
| } | |||
| return row; | |||
| } | |||
| private void mergeRegion(int firstRow, int lastRow, int firstCol, int lastCol) { | |||
| LOGGER.debug("Merge Region, From Row [{}], To [{}].", firstRow, lastRow); | |||
| LOGGER.debug("From Col [{}], To [{}].", firstCol, lastCol); | |||
| sheet.addMergedRegion(new CellRangeAddress(firstRow, lastRow, firstCol, lastCol)); | |||
| } | |||
| } | |||
| @@ -1,304 +1,304 @@ | |||
| package cn.afterturn.easypoi.excel.html.css; | |||
| import static cn.afterturn.easypoi.excel.html.entity.HtmlCssConstant.*; | |||
| import java.util.HashMap; | |||
| import java.util.HashSet; | |||
| import java.util.Map; | |||
| import java.util.Set; | |||
| import java.util.regex.Matcher; | |||
| import java.util.regex.Pattern; | |||
| import org.apache.commons.lang3.ArrayUtils; | |||
| import org.apache.commons.lang3.StringUtils; | |||
| import org.slf4j.Logger; | |||
| import org.slf4j.LoggerFactory; | |||
| import cn.afterturn.easypoi.excel.html.entity.style.CellStyleBorderEntity; | |||
| import cn.afterturn.easypoi.excel.html.entity.style.CellStyleEntity; | |||
| import cn.afterturn.easypoi.excel.html.entity.style.CssStyleFontEnity; | |||
| import cn.afterturn.easypoi.util.PoiCssUtils; | |||
| /** | |||
| * 把Css样式解析成对应的Model | |||
| * @author JueYue | |||
| * 2017年3月19日 | |||
| */ | |||
| public class CssParseServer { | |||
| private static final Logger log = LoggerFactory.getLogger(CssParseServer.class); | |||
| private static final Pattern STYLE_PATTERN = Pattern.compile("(?:^|\\s+)(italic|oblique)(?:\\s+|$)"); | |||
| private static final Pattern WEIGHT_PATTERN = Pattern.compile("(?:^|\\s+)(bold(?:er)?|[7-9]00)(?:\\s+|$)"); | |||
| @SuppressWarnings("serial") | |||
| private final static Set<String> BORDER_STYLES = new HashSet<String>() { | |||
| { | |||
| // Specifies no border | |||
| add(NONE); | |||
| // The same as "none", except in border conflict resolution for table elements | |||
| add(HIDDEN); | |||
| // Specifies a dotted border | |||
| add(DOTTED); | |||
| // Specifies a dashed border | |||
| add(DASHED); | |||
| // Specifies a solid border | |||
| add(SOLID); | |||
| // Specifies a double border | |||
| add(DOUBLE); | |||
| } | |||
| }; | |||
| public CellStyleEntity parseStyle(String style) { | |||
| Map<String, String> mapStyle = new HashMap<String, String>(); | |||
| for (String s : style.split("\\s*;\\s*")) { | |||
| if (StringUtils.isNotBlank(s)) { | |||
| String[] ss = s.split("\\s*\\:\\s*"); | |||
| if (ss.length == 2 && StringUtils.isNotBlank(ss[0]) | |||
| && StringUtils.isNotBlank(ss[1])) { | |||
| String attrName = ss[0].toLowerCase(); | |||
| String attrValue = ss[1]; | |||
| // do not change font name | |||
| if (!FONT.equals(attrName) && !FONT_FAMILY.equals(attrName)) { | |||
| attrValue = attrValue.toLowerCase(); | |||
| } | |||
| mapStyle.put(attrName, attrValue); | |||
| } | |||
| } | |||
| } | |||
| parseFontAttr(mapStyle); | |||
| parseBackground(mapStyle); | |||
| parseBorder(mapStyle); | |||
| return mapToCellStyleEntity(mapStyle); | |||
| } | |||
| private CellStyleEntity mapToCellStyleEntity(Map<String, String> mapStyle) { | |||
| CellStyleEntity entity = new CellStyleEntity(); | |||
| entity.setAlign(mapStyle.get(TEXT_ALIGN)); | |||
| entity.setVetical(mapStyle.get(VETICAL_ALIGN)); | |||
| entity.setBackground(parseBackground(mapStyle)); | |||
| entity.setHeight(mapStyle.get(HEIGHT)); | |||
| entity.setWidth(mapStyle.get(WIDTH)); | |||
| entity.setFont(getCssStyleFontEnity(mapStyle)); | |||
| entity.setBackground(mapStyle.get(BACKGROUND_COLOR)); | |||
| entity.setBorder(getCssStyleBorderEntity(mapStyle)); | |||
| return entity; | |||
| } | |||
| private CellStyleBorderEntity getCssStyleBorderEntity(Map<String, String> mapStyle) { | |||
| CellStyleBorderEntity border = new CellStyleBorderEntity(); | |||
| border.setBorderTopColor(mapStyle.get(BORDER + "-" + TOP + "-" + COLOR)); | |||
| border.setBorderBottomColor(mapStyle.get(BORDER + "-" + BOTTOM + "-" + COLOR)); | |||
| border.setBorderLeftColor(mapStyle.get(BORDER + "-" + LEFT + "-" + COLOR)); | |||
| border.setBorderRightColor(mapStyle.get(BORDER + "-" + RIGHT + "-" + COLOR)); | |||
| border.setBorderTopWidth(mapStyle.get(BORDER + "-" + TOP + "-" + WIDTH)); | |||
| border.setBorderBottomWidth(mapStyle.get(BORDER + "-" + BOTTOM + "-" + WIDTH)); | |||
| border.setBorderLeftWidth(mapStyle.get(BORDER + "-" + LEFT + "-" + WIDTH)); | |||
| border.setBorderRightWidth(mapStyle.get(BORDER + "-" + RIGHT + "-" + WIDTH)); | |||
| border.setBorderTopStyle(mapStyle.get(BORDER + "-" + TOP + "-" + STYLE)); | |||
| border.setBorderBottomStyle(mapStyle.get(BORDER + "-" + BOTTOM + "-" + STYLE)); | |||
| border.setBorderLeftStyle(mapStyle.get(BORDER + "-" + LEFT + "-" + STYLE)); | |||
| border.setBorderRightStyle(mapStyle.get(BORDER + "-" + RIGHT + "-" + STYLE)); | |||
| return border; | |||
| } | |||
| private CssStyleFontEnity getCssStyleFontEnity(Map<String, String> style) { | |||
| CssStyleFontEnity font = new CssStyleFontEnity(); | |||
| font.setStyle(style.get(FONT_STYLE)); | |||
| int fontSize = PoiCssUtils.getInt(style.get(FONT_SIZE)); | |||
| if (fontSize > 0) { | |||
| font.setSize(fontSize); | |||
| } | |||
| font.setWeight(style.get(FONT_WEIGHT)); | |||
| font.setFamily(style.get(FONT_FAMILY)); | |||
| font.setDecoration(style.get(TEXT_DECORATION)); | |||
| font.setColor(style.get(COLOR)); | |||
| return font; | |||
| } | |||
| public void parseBorder(Map<String, String> style) { | |||
| for (String pos : new String[] { null, TOP, RIGHT, BOTTOM, LEFT }) { | |||
| // border[-attr] | |||
| if (pos == null) { | |||
| setBorderAttr(style, pos, style.get(BORDER)); | |||
| setBorderAttr(style, pos, style.get(BORDER + "-" + COLOR)); | |||
| setBorderAttr(style, pos, style.get(BORDER + "-" + WIDTH)); | |||
| setBorderAttr(style, pos, style.get(BORDER + "-" + STYLE)); | |||
| } | |||
| // border-pos[-attr] | |||
| else { | |||
| setBorderAttr(style, pos, style.get(BORDER + "-" + pos)); | |||
| for (String attr : new String[] { COLOR, WIDTH, STYLE }) { | |||
| String attrName = BORDER + "-" + pos + "-" + attr; | |||
| String attrValue = style.get(attrName); | |||
| if (StringUtils.isNotBlank(attrValue)) { | |||
| style.put(attrName, attrValue); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| private void setBorderAttr(Map<String, String> mapBorder, String pos, String value) { | |||
| if (StringUtils.isNotBlank(value)) { | |||
| String borderColor = null; | |||
| for (String borderAttr : value.split("\\s+")) { | |||
| if ((borderColor = PoiCssUtils.processColor(borderAttr)) != null) { | |||
| setBorderAttr(mapBorder, pos, COLOR, borderColor); | |||
| } else if (PoiCssUtils.isNum(borderAttr)) { | |||
| setBorderAttr(mapBorder, pos, WIDTH, borderAttr); | |||
| } else if (BORDER_STYLES.contains(borderAttr)) { | |||
| setBorderAttr(mapBorder, pos, STYLE, borderAttr); | |||
| } else { | |||
| log.info("Border Attr [{}] Is Not Suppoted.", borderAttr); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| private void setBorderAttr(Map<String, String> mapBorder, String pos, String attr, | |||
| String value) { | |||
| if (StringUtils.isNotBlank(pos)) { | |||
| mapBorder.put(BORDER + "-" + pos + "-" + attr, value); | |||
| } else { | |||
| for (String name : new String[] { TOP, RIGHT, BOTTOM, LEFT }) { | |||
| mapBorder.put(BORDER + "-" + name + "-" + attr, value); | |||
| } | |||
| } | |||
| } | |||
| private void parseFontAttr(Map<String, String> mapRtn) { | |||
| log.debug("Parse Font Style."); | |||
| // color | |||
| String color = PoiCssUtils.processColor(mapRtn.get(COLOR)); | |||
| if (StringUtils.isNotBlank(color)) { | |||
| log.debug("Text Color [{}] Found.", color); | |||
| mapRtn.put(COLOR, color); | |||
| } | |||
| // font | |||
| String font = mapRtn.get(FONT); | |||
| if (StringUtils.isNotBlank(font) | |||
| && !ArrayUtils.contains(new String[] { "small-caps", "caption", "icon", "menu", | |||
| "message-box", "small-caption", "status-bar" }, | |||
| font)) { | |||
| log.debug("Parse Font Attr [{}].", font); | |||
| String[] ignoreStyles = new String[] { "normal", | |||
| // font weight normal | |||
| "[1-3]00" }; | |||
| StringBuffer sbFont = new StringBuffer( | |||
| font.replaceAll("^|\\s*" + StringUtils.join(ignoreStyles, "|") + "\\s+|$", " ")); | |||
| log.debug("Font Attr [{}] After Process Ingore.", sbFont); | |||
| // style | |||
| Matcher m = STYLE_PATTERN.matcher(sbFont.toString()); | |||
| if (m.find()) { | |||
| sbFont.setLength(0); | |||
| if (log.isDebugEnabled()) { | |||
| log.debug("Font Style [{}] Found.", m.group(1)); | |||
| } | |||
| mapRtn.put(FONT_STYLE, ITALIC); | |||
| m.appendReplacement(sbFont, " "); | |||
| m.appendTail(sbFont); | |||
| } | |||
| // weight | |||
| m = WEIGHT_PATTERN.matcher(sbFont.toString()); | |||
| if (m.find()) { | |||
| sbFont.setLength(0); | |||
| if (log.isDebugEnabled()) { | |||
| log.debug("Font Weight [{}](bold) Found.", m.group(1)); | |||
| } | |||
| mapRtn.put(FONT_WEIGHT, BOLD); | |||
| m.appendReplacement(sbFont, " "); | |||
| m.appendTail(sbFont); | |||
| } | |||
| // size xx-small | x-small | small | medium | large | x-large | xx-large | 18px [/2] | |||
| m = Pattern.compile( | |||
| // before blank or start | |||
| new StringBuilder("(?:^|\\s+)") | |||
| // font size | |||
| .append("(xx-small|x-small|small|medium|large|x-large|xx-large|").append("(?:") | |||
| .append(PATTERN_LENGTH).append("))") | |||
| // line height | |||
| .append("(?:\\s*\\/\\s*(").append(PATTERN_LENGTH).append("))?") | |||
| // after blank or end | |||
| .append("(?:\\s+|$)").toString()) | |||
| .matcher(sbFont.toString()); | |||
| if (m.find()) { | |||
| sbFont.setLength(0); | |||
| log.debug("Font Size[/line-height] [{}] Found.", m.group()); | |||
| String fontSize = m.group(1); | |||
| if (StringUtils.isNotBlank(fontSize)) { | |||
| fontSize = StringUtils.deleteWhitespace(fontSize); | |||
| log.debug("Font Size [{}].", fontSize); | |||
| if (fontSize.matches(PATTERN_LENGTH)) { | |||
| mapRtn.put(FONT_SIZE, fontSize); | |||
| } else { | |||
| log.info("Font Size [{}] Not Supported, Ignore.", fontSize); | |||
| } | |||
| } | |||
| String lineHeight = m.group(2); | |||
| if (StringUtils.isNotBlank(lineHeight)) { | |||
| log.info("Line Height [{}] Not Supported, Ignore.", lineHeight); | |||
| } | |||
| m.appendReplacement(sbFont, " "); | |||
| m.appendTail(sbFont); | |||
| } | |||
| // font family | |||
| if (sbFont.length() > 0) { | |||
| log.debug("Font Families [{}].", sbFont); | |||
| // trim & remove '" | |||
| String fontFamily = sbFont.toString().split("\\s*,\\s*")[0].trim() | |||
| .replaceAll("'|\"", ""); | |||
| log.debug("Use First Font Family [{}].", fontFamily); | |||
| mapRtn.put(FONT_FAMILY, fontFamily); | |||
| } | |||
| } | |||
| font = mapRtn.get(FONT_STYLE); | |||
| if (ArrayUtils.contains(new String[] { ITALIC, "oblique" }, font)) { | |||
| log.debug("Font Italic [{}] Found.", font); | |||
| mapRtn.put(FONT_STYLE, ITALIC); | |||
| } | |||
| font = mapRtn.get(FONT_WEIGHT); | |||
| if (StringUtils.isNotBlank(font) && Pattern.matches("^bold(?:er)?|[7-9]00$", font)) { | |||
| log.debug("Font Weight [{}](bold) Found.", font); | |||
| mapRtn.put(FONT_WEIGHT, BOLD); | |||
| } | |||
| font = mapRtn.get(FONT_SIZE); | |||
| if (!PoiCssUtils.isNum(font)) { | |||
| log.debug("Font Size [{}] Error.", font); | |||
| mapRtn.remove(FONT_SIZE); | |||
| } | |||
| } | |||
| private String parseBackground(Map<String, String> style) { | |||
| String bg = style.get(BACKGROUND); | |||
| String bgColor = null; | |||
| if (StringUtils.isNotBlank(bg)) { | |||
| for (String bgAttr : bg.split("(?<=\\)|\\w|%)\\s+(?=\\w)")) { | |||
| if ((bgColor = PoiCssUtils.processColor(bgAttr)) != null) { | |||
| style.put(BACKGROUND_COLOR, bgColor); | |||
| break; | |||
| } | |||
| } | |||
| } | |||
| bg = style.get(BACKGROUND_COLOR); | |||
| if (StringUtils.isNotBlank(bg) && (bgColor = PoiCssUtils.processColor(bg)) != null) { | |||
| style.put(BACKGROUND_COLOR, bgColor); | |||
| } | |||
| if (bgColor != null) { | |||
| bgColor = style.get(BACKGROUND_COLOR); | |||
| if ("#ffffff".equals(bgColor)) { | |||
| style.remove(BACKGROUND_COLOR); | |||
| } | |||
| } | |||
| return null; | |||
| } | |||
| } | |||
| package cn.afterturn.easypoi.excel.html.css; | |||
| import static cn.afterturn.easypoi.excel.html.entity.HtmlCssConstant.*; | |||
| import java.util.HashMap; | |||
| import java.util.HashSet; | |||
| import java.util.Map; | |||
| import java.util.Set; | |||
| import java.util.regex.Matcher; | |||
| import java.util.regex.Pattern; | |||
| import org.apache.commons.lang3.ArrayUtils; | |||
| import org.apache.commons.lang3.StringUtils; | |||
| import org.slf4j.Logger; | |||
| import org.slf4j.LoggerFactory; | |||
| import cn.afterturn.easypoi.excel.html.entity.style.CellStyleBorderEntity; | |||
| import cn.afterturn.easypoi.excel.html.entity.style.CellStyleEntity; | |||
| import cn.afterturn.easypoi.excel.html.entity.style.CssStyleFontEnity; | |||
| import cn.afterturn.easypoi.util.PoiCssUtils; | |||
| /** | |||
| * 把Css样式解析成对应的Model | |||
| * @author JueYue | |||
| * 2017年3月19日 | |||
| */ | |||
| public class CssParseService { | |||
| private static final Logger log = LoggerFactory.getLogger(CssParseService.class); | |||
| private static final Pattern STYLE_PATTERN = Pattern.compile("(?:^|\\s+)(italic|oblique)(?:\\s+|$)"); | |||
| private static final Pattern WEIGHT_PATTERN = Pattern.compile("(?:^|\\s+)(bold(?:er)?|[7-9]00)(?:\\s+|$)"); | |||
| @SuppressWarnings("serial") | |||
| private final static Set<String> BORDER_STYLES = new HashSet<String>() { | |||
| { | |||
| // Specifies no border | |||
| add(NONE); | |||
| // The same as "none", except in border conflict resolution for table elements | |||
| add(HIDDEN); | |||
| // Specifies a dotted border | |||
| add(DOTTED); | |||
| // Specifies a dashed border | |||
| add(DASHED); | |||
| // Specifies a solid border | |||
| add(SOLID); | |||
| // Specifies a double border | |||
| add(DOUBLE); | |||
| } | |||
| }; | |||
| public CellStyleEntity parseStyle(String style) { | |||
| Map<String, String> mapStyle = new HashMap<String, String>(); | |||
| for (String s : style.split("\\s*;\\s*")) { | |||
| if (StringUtils.isNotBlank(s)) { | |||
| String[] ss = s.split("\\s*\\:\\s*"); | |||
| if (ss.length == 2 && StringUtils.isNotBlank(ss[0]) | |||
| && StringUtils.isNotBlank(ss[1])) { | |||
| String attrName = ss[0].toLowerCase(); | |||
| String attrValue = ss[1]; | |||
| // do not change font name | |||
| if (!FONT.equals(attrName) && !FONT_FAMILY.equals(attrName)) { | |||
| attrValue = attrValue.toLowerCase(); | |||
| } | |||
| mapStyle.put(attrName, attrValue); | |||
| } | |||
| } | |||
| } | |||
| parseFontAttr(mapStyle); | |||
| parseBackground(mapStyle); | |||
| parseBorder(mapStyle); | |||
| return mapToCellStyleEntity(mapStyle); | |||
| } | |||
| private CellStyleEntity mapToCellStyleEntity(Map<String, String> mapStyle) { | |||
| CellStyleEntity entity = new CellStyleEntity(); | |||
| entity.setAlign(mapStyle.get(TEXT_ALIGN)); | |||
| entity.setVetical(mapStyle.get(VETICAL_ALIGN)); | |||
| entity.setBackground(parseBackground(mapStyle)); | |||
| entity.setHeight(mapStyle.get(HEIGHT)); | |||
| entity.setWidth(mapStyle.get(WIDTH)); | |||
| entity.setFont(getCssStyleFontEnity(mapStyle)); | |||
| entity.setBackground(mapStyle.get(BACKGROUND_COLOR)); | |||
| entity.setBorder(getCssStyleBorderEntity(mapStyle)); | |||
| return entity; | |||
| } | |||
| private CellStyleBorderEntity getCssStyleBorderEntity(Map<String, String> mapStyle) { | |||
| CellStyleBorderEntity border = new CellStyleBorderEntity(); | |||
| border.setBorderTopColor(mapStyle.get(BORDER + "-" + TOP + "-" + COLOR)); | |||
| border.setBorderBottomColor(mapStyle.get(BORDER + "-" + BOTTOM + "-" + COLOR)); | |||
| border.setBorderLeftColor(mapStyle.get(BORDER + "-" + LEFT + "-" + COLOR)); | |||
| border.setBorderRightColor(mapStyle.get(BORDER + "-" + RIGHT + "-" + COLOR)); | |||
| border.setBorderTopWidth(mapStyle.get(BORDER + "-" + TOP + "-" + WIDTH)); | |||
| border.setBorderBottomWidth(mapStyle.get(BORDER + "-" + BOTTOM + "-" + WIDTH)); | |||
| border.setBorderLeftWidth(mapStyle.get(BORDER + "-" + LEFT + "-" + WIDTH)); | |||
| border.setBorderRightWidth(mapStyle.get(BORDER + "-" + RIGHT + "-" + WIDTH)); | |||
| border.setBorderTopStyle(mapStyle.get(BORDER + "-" + TOP + "-" + STYLE)); | |||
| border.setBorderBottomStyle(mapStyle.get(BORDER + "-" + BOTTOM + "-" + STYLE)); | |||
| border.setBorderLeftStyle(mapStyle.get(BORDER + "-" + LEFT + "-" + STYLE)); | |||
| border.setBorderRightStyle(mapStyle.get(BORDER + "-" + RIGHT + "-" + STYLE)); | |||
| return border; | |||
| } | |||
| private CssStyleFontEnity getCssStyleFontEnity(Map<String, String> style) { | |||
| CssStyleFontEnity font = new CssStyleFontEnity(); | |||
| font.setStyle(style.get(FONT_STYLE)); | |||
| int fontSize = PoiCssUtils.getInt(style.get(FONT_SIZE)); | |||
| if (fontSize > 0) { | |||
| font.setSize(fontSize); | |||
| } | |||
| font.setWeight(style.get(FONT_WEIGHT)); | |||
| font.setFamily(style.get(FONT_FAMILY)); | |||
| font.setDecoration(style.get(TEXT_DECORATION)); | |||
| font.setColor(style.get(COLOR)); | |||
| return font; | |||
| } | |||
| public void parseBorder(Map<String, String> style) { | |||
| for (String pos : new String[] { null, TOP, RIGHT, BOTTOM, LEFT }) { | |||
| // border[-attr] | |||
| if (pos == null) { | |||
| setBorderAttr(style, pos, style.get(BORDER)); | |||
| setBorderAttr(style, pos, style.get(BORDER + "-" + COLOR)); | |||
| setBorderAttr(style, pos, style.get(BORDER + "-" + WIDTH)); | |||
| setBorderAttr(style, pos, style.get(BORDER + "-" + STYLE)); | |||
| } | |||
| // border-pos[-attr] | |||
| else { | |||
| setBorderAttr(style, pos, style.get(BORDER + "-" + pos)); | |||
| for (String attr : new String[] { COLOR, WIDTH, STYLE }) { | |||
| String attrName = BORDER + "-" + pos + "-" + attr; | |||
| String attrValue = style.get(attrName); | |||
| if (StringUtils.isNotBlank(attrValue)) { | |||
| style.put(attrName, attrValue); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| } | |||
| private void setBorderAttr(Map<String, String> mapBorder, String pos, String value) { | |||
| if (StringUtils.isNotBlank(value)) { | |||
| String borderColor = null; | |||
| for (String borderAttr : value.split("\\s+")) { | |||
| if ((borderColor = PoiCssUtils.processColor(borderAttr)) != null) { | |||
| setBorderAttr(mapBorder, pos, COLOR, borderColor); | |||
| } else if (PoiCssUtils.isNum(borderAttr)) { | |||
| setBorderAttr(mapBorder, pos, WIDTH, borderAttr); | |||
| } else if (BORDER_STYLES.contains(borderAttr)) { | |||
| setBorderAttr(mapBorder, pos, STYLE, borderAttr); | |||
| } else { | |||
| log.info("Border Attr [{}] Is Not Suppoted.", borderAttr); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| private void setBorderAttr(Map<String, String> mapBorder, String pos, String attr, | |||
| String value) { | |||
| if (StringUtils.isNotBlank(pos)) { | |||
| mapBorder.put(BORDER + "-" + pos + "-" + attr, value); | |||
| } else { | |||
| for (String name : new String[] { TOP, RIGHT, BOTTOM, LEFT }) { | |||
| mapBorder.put(BORDER + "-" + name + "-" + attr, value); | |||
| } | |||
| } | |||
| } | |||
| private void parseFontAttr(Map<String, String> mapRtn) { | |||
| log.debug("Parse Font Style."); | |||
| // color | |||
| String color = PoiCssUtils.processColor(mapRtn.get(COLOR)); | |||
| if (StringUtils.isNotBlank(color)) { | |||
| log.debug("Text Color [{}] Found.", color); | |||
| mapRtn.put(COLOR, color); | |||
| } | |||
| // font | |||
| String font = mapRtn.get(FONT); | |||
| if (StringUtils.isNotBlank(font) | |||
| && !ArrayUtils.contains(new String[] { "small-caps", "caption", "icon", "menu", | |||
| "message-box", "small-caption", "status-bar" }, | |||
| font)) { | |||
| log.debug("Parse Font Attr [{}].", font); | |||
| String[] ignoreStyles = new String[] { "normal", | |||
| // font weight normal | |||
| "[1-3]00" }; | |||
| StringBuffer sbFont = new StringBuffer( | |||
| font.replaceAll("^|\\s*" + StringUtils.join(ignoreStyles, "|") + "\\s+|$", " ")); | |||
| log.debug("Font Attr [{}] After Process Ingore.", sbFont); | |||
| // style | |||
| Matcher m = STYLE_PATTERN.matcher(sbFont.toString()); | |||
| if (m.find()) { | |||
| sbFont.setLength(0); | |||
| if (log.isDebugEnabled()) { | |||
| log.debug("Font Style [{}] Found.", m.group(1)); | |||
| } | |||
| mapRtn.put(FONT_STYLE, ITALIC); | |||
| m.appendReplacement(sbFont, " "); | |||
| m.appendTail(sbFont); | |||
| } | |||
| // weight | |||
| m = WEIGHT_PATTERN.matcher(sbFont.toString()); | |||
| if (m.find()) { | |||
| sbFont.setLength(0); | |||
| if (log.isDebugEnabled()) { | |||
| log.debug("Font Weight [{}](bold) Found.", m.group(1)); | |||
| } | |||
| mapRtn.put(FONT_WEIGHT, BOLD); | |||
| m.appendReplacement(sbFont, " "); | |||
| m.appendTail(sbFont); | |||
| } | |||
| // size xx-small | x-small | small | medium | large | x-large | xx-large | 18px [/2] | |||
| m = Pattern.compile( | |||
| // before blank or start | |||
| new StringBuilder("(?:^|\\s+)") | |||
| // font size | |||
| .append("(xx-small|x-small|small|medium|large|x-large|xx-large|").append("(?:") | |||
| .append(PATTERN_LENGTH).append("))") | |||
| // line height | |||
| .append("(?:\\s*\\/\\s*(").append(PATTERN_LENGTH).append("))?") | |||
| // after blank or end | |||
| .append("(?:\\s+|$)").toString()) | |||
| .matcher(sbFont.toString()); | |||
| if (m.find()) { | |||
| sbFont.setLength(0); | |||
| log.debug("Font Size[/line-height] [{}] Found.", m.group()); | |||
| String fontSize = m.group(1); | |||
| if (StringUtils.isNotBlank(fontSize)) { | |||
| fontSize = StringUtils.deleteWhitespace(fontSize); | |||
| log.debug("Font Size [{}].", fontSize); | |||
| if (fontSize.matches(PATTERN_LENGTH)) { | |||
| mapRtn.put(FONT_SIZE, fontSize); | |||
| } else { | |||
| log.info("Font Size [{}] Not Supported, Ignore.", fontSize); | |||
| } | |||
| } | |||
| String lineHeight = m.group(2); | |||
| if (StringUtils.isNotBlank(lineHeight)) { | |||
| log.info("Line Height [{}] Not Supported, Ignore.", lineHeight); | |||
| } | |||
| m.appendReplacement(sbFont, " "); | |||
| m.appendTail(sbFont); | |||
| } | |||
| // font family | |||
| if (sbFont.length() > 0) { | |||
| log.debug("Font Families [{}].", sbFont); | |||
| // trim & remove '" | |||
| String fontFamily = sbFont.toString().split("\\s*,\\s*")[0].trim() | |||
| .replaceAll("'|\"", ""); | |||
| log.debug("Use First Font Family [{}].", fontFamily); | |||
| mapRtn.put(FONT_FAMILY, fontFamily); | |||
| } | |||
| } | |||
| font = mapRtn.get(FONT_STYLE); | |||
| if (ArrayUtils.contains(new String[] { ITALIC, "oblique" }, font)) { | |||
| log.debug("Font Italic [{}] Found.", font); | |||
| mapRtn.put(FONT_STYLE, ITALIC); | |||
| } | |||
| font = mapRtn.get(FONT_WEIGHT); | |||
| if (StringUtils.isNotBlank(font) && Pattern.matches("^bold(?:er)?|[7-9]00$", font)) { | |||
| log.debug("Font Weight [{}](bold) Found.", font); | |||
| mapRtn.put(FONT_WEIGHT, BOLD); | |||
| } | |||
| font = mapRtn.get(FONT_SIZE); | |||
| if (!PoiCssUtils.isNum(font)) { | |||
| log.debug("Font Size [{}] Error.", font); | |||
| mapRtn.remove(FONT_SIZE); | |||
| } | |||
| } | |||
| private String parseBackground(Map<String, String> style) { | |||
| String bg = style.get(BACKGROUND); | |||
| String bgColor = null; | |||
| if (StringUtils.isNotBlank(bg)) { | |||
| for (String bgAttr : bg.split("(?<=\\)|\\w|%)\\s+(?=\\w)")) { | |||
| if ((bgColor = PoiCssUtils.processColor(bgAttr)) != null) { | |||
| style.put(BACKGROUND_COLOR, bgColor); | |||
| break; | |||
| } | |||
| } | |||
| } | |||
| bg = style.get(BACKGROUND_COLOR); | |||
| if (StringUtils.isNotBlank(bg) && (bgColor = PoiCssUtils.processColor(bg)) != null) { | |||
| style.put(BACKGROUND_COLOR, bgColor); | |||
| } | |||
| if (bgColor != null) { | |||
| bgColor = style.get(BACKGROUND_COLOR); | |||
| if ("#ffffff".equals(bgColor)) { | |||
| style.remove(BACKGROUND_COLOR); | |||
| } | |||
| } | |||
| return null; | |||
| } | |||
| } | |||
| @@ -1,355 +1,355 @@ | |||
| /** | |||
| * Copyright 2013-2015 JueYue (qrb.jueyue@gmail.com) | |||
| * | |||
| * Licensed under the Apache License, Version 2.0 (the "License"); | |||
| * you may not use this file except in compliance with the License. | |||
| * You may obtain a copy of the License at | |||
| * | |||
| * http://www.apache.org/licenses/LICENSE-2.0 | |||
| * | |||
| * Unless required by applicable law or agreed to in writing, software | |||
| * distributed under the License is distributed on an "AS IS" BASIS, | |||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
| * See the License for the specific language governing permissions and | |||
| * limitations under the License. | |||
| */ | |||
| package cn.afterturn.easypoi.excel.imports; | |||
| import java.lang.reflect.Method; | |||
| import java.lang.reflect.Type; | |||
| import java.math.BigDecimal; | |||
| import java.sql.Time; | |||
| import java.sql.Timestamp; | |||
| import java.text.ParseException; | |||
| import java.text.SimpleDateFormat; | |||
| import java.util.Arrays; | |||
| import java.util.Date; | |||
| import java.util.List; | |||
| import java.util.Map; | |||
| import org.apache.commons.lang3.StringUtils; | |||
| import org.apache.poi.ss.usermodel.Cell; | |||
| import org.apache.poi.ss.usermodel.CellType; | |||
| import org.apache.poi.ss.usermodel.DateUtil; | |||
| import org.slf4j.Logger; | |||
| import org.slf4j.LoggerFactory; | |||
| import cn.afterturn.easypoi.excel.entity.params.ExcelImportEntity; | |||
| import cn.afterturn.easypoi.excel.entity.sax.SaxReadCellEntity; | |||
| import cn.afterturn.easypoi.exception.excel.ExcelImportException; | |||
| import cn.afterturn.easypoi.exception.excel.enums.ExcelImportEnum; | |||
| import cn.afterturn.easypoi.handler.inter.IExcelDataHandler; | |||
| import cn.afterturn.easypoi.util.PoiPublicUtil; | |||
| /** | |||
| * Cell 取值服务 | |||
| * 判断类型处理数据 1.判断Excel中的类型 2.根据replace替换值 3.handler处理数据 4.判断返回类型转化数据返回 | |||
| * | |||
| * @author JueYue | |||
| * 2014年6月26日 下午10:42:28 | |||
| */ | |||
| public class CellValueServer { | |||
| private static final Logger LOGGER = LoggerFactory.getLogger(CellValueServer.class); | |||
| private List<String> hanlderList = null; | |||
| /** | |||
| * 获取单元格内的值 | |||
| * | |||
| * @param cell | |||
| * @param entity | |||
| * @return | |||
| */ | |||
| private Object getCellValue(String xclass, Cell cell, ExcelImportEntity entity) { | |||
| if (cell == null) { | |||
| return ""; | |||
| } | |||
| Object result = null; | |||
| if ("class java.util.Date".equals(xclass) || "class java.sql.Date".equals(xclass) | |||
| || ("class java.sql.Time").equals(xclass) | |||
| || ("class java.sql.Timestamp").equals(xclass)) { | |||
| /* | |||
| if (Cell.CELL_TYPE_NUMERIC == cell.getCellType()) { | |||
| // 日期格式 | |||
| result = cell.getDateCellValue(); | |||
| } else { | |||
| cell.setCellType(Cell.CELL_TYPE_STRING); | |||
| result = getDateData(entity, cell.getStringCellValue()); | |||
| }*/ | |||
| //FIX: 单元格yyyyMMdd数字时候使用 cell.getDateCellValue() 解析出的日期错误 | |||
| if (Cell.CELL_TYPE_NUMERIC == cell.getCellType() && DateUtil.isCellDateFormatted(cell)) { | |||
| result = DateUtil.getJavaDate(cell.getNumericCellValue()); | |||
| } else { | |||
| cell.setCellType(CellType.STRING); | |||
| result = getDateData(entity, cell.getStringCellValue()); | |||
| } | |||
| if (("class java.sql.Date").equals(xclass)) { | |||
| result = new java.sql.Date(((Date) result).getTime()); | |||
| } | |||
| if (("class java.sql.Time").equals(xclass)) { | |||
| result = new Time(((Date) result).getTime()); | |||
| } | |||
| if (("class java.sql.Timestamp").equals(xclass)) { | |||
| result = new Timestamp(((Date) result).getTime()); | |||
| } | |||
| } else if (Cell.CELL_TYPE_NUMERIC == cell.getCellType() && DateUtil.isCellDateFormatted(cell)) { | |||
| result = DateUtil.getJavaDate(cell.getNumericCellValue()); | |||
| } else { | |||
| switch (cell.getCellType()) { | |||
| case Cell.CELL_TYPE_STRING: | |||
| result = cell.getRichStringCellValue() == null ? "" | |||
| : cell.getRichStringCellValue().getString(); | |||
| break; | |||
| case Cell.CELL_TYPE_NUMERIC: | |||
| if (DateUtil.isCellDateFormatted(cell)) { | |||
| if ("class java.lang.String".equals(xclass)) { | |||
| result = formateDate(entity, cell.getDateCellValue()); | |||
| } | |||
| } else { | |||
| result = readNumericCell(cell); | |||
| } | |||
| break; | |||
| case Cell.CELL_TYPE_BOOLEAN: | |||
| result = Boolean.toString(cell.getBooleanCellValue()); | |||
| break; | |||
| case Cell.CELL_TYPE_BLANK: | |||
| break; | |||
| case Cell.CELL_TYPE_ERROR: | |||
| break; | |||
| case Cell.CELL_TYPE_FORMULA: | |||
| try { | |||
| result = readNumericCell(cell); | |||
| } catch (Exception e1) { | |||
| try { | |||
| result = cell.getRichStringCellValue() == null ? "" | |||
| : cell.getRichStringCellValue().getString(); | |||
| } catch (Exception e2) { | |||
| throw new RuntimeException("获取公式类型的单元格失败", e2); | |||
| } | |||
| } | |||
| break; | |||
| default: | |||
| break; | |||
| } | |||
| } | |||
| return result; | |||
| } | |||
| private Object readNumericCell(Cell cell) { | |||
| Object result = null; | |||
| double value = cell.getNumericCellValue(); | |||
| if (((int) value) == value) { | |||
| result = (int) value; | |||
| } else { | |||
| result = value; | |||
| } | |||
| return result; | |||
| } | |||
| /** | |||
| * 获取日期类型数据 | |||
| * | |||
| * @author JueYue | |||
| * 2013年11月26日 | |||
| * @param entity | |||
| * @param value | |||
| * @return | |||
| */ | |||
| private Date getDateData(ExcelImportEntity entity, String value) { | |||
| if (StringUtils.isNotEmpty(entity.getFormat()) && StringUtils.isNotEmpty(value)) { | |||
| SimpleDateFormat format = new SimpleDateFormat(entity.getFormat()); | |||
| try { | |||
| return format.parse(value); | |||
| } catch (ParseException e) { | |||
| LOGGER.error("时间格式化失败,格式化:{},值:{}", entity.getFormat(), value); | |||
| throw new ExcelImportException(ExcelImportEnum.GET_VALUE_ERROR); | |||
| } | |||
| } | |||
| return null; | |||
| } | |||
| private String formateDate(ExcelImportEntity entity, Date value) { | |||
| if (StringUtils.isNotEmpty(entity.getFormat()) && value != null) { | |||
| SimpleDateFormat format = new SimpleDateFormat(entity.getFormat()); | |||
| return format.format(value); | |||
| } | |||
| return null; | |||
| } | |||
| /** | |||
| * 获取cell的值 | |||
| * | |||
| * @param object | |||
| * @param excelParams | |||
| * @param cell | |||
| * @param titleString | |||
| */ | |||
| public Object getValue(IExcelDataHandler<?> dataHanlder, Object object, Cell cell, | |||
| Map<String, ExcelImportEntity> excelParams, | |||
| String titleString) throws Exception { | |||
| ExcelImportEntity entity = excelParams.get(titleString); | |||
| String xclass = "class java.lang.Object"; | |||
| if (!(object instanceof Map)) { | |||
| Method setMethod = entity.getMethods() != null && entity.getMethods().size() > 0 | |||
| ? entity.getMethods().get(entity.getMethods().size() - 1) : entity.getMethod(); | |||
| Type[] ts = setMethod.getGenericParameterTypes(); | |||
| xclass = ts[0].toString(); | |||
| } | |||
| Object result = getCellValue(xclass, cell, entity); | |||
| if (entity != null) { | |||
| result = hanlderSuffix(entity.getSuffix(), result); | |||
| result = replaceValue(entity.getReplace(), result); | |||
| } | |||
| result = hanlderValue(dataHanlder, object, result, titleString); | |||
| return getValueByType(xclass, result, entity); | |||
| } | |||
| /** | |||
| * 获取cell值 | |||
| * @param dataHanlder | |||
| * @param object | |||
| * @param cellEntity | |||
| * @param excelParams | |||
| * @param titleString | |||
| * @return | |||
| */ | |||
| public Object getValue(IExcelDataHandler<?> dataHanlder, Object object, | |||
| SaxReadCellEntity cellEntity, Map<String, ExcelImportEntity> excelParams, | |||
| String titleString) { | |||
| ExcelImportEntity entity = excelParams.get(titleString); | |||
| Method setMethod = entity.getMethods() != null && entity.getMethods().size() > 0 | |||
| ? entity.getMethods().get(entity.getMethods().size() - 1) : entity.getMethod(); | |||
| Type[] ts = setMethod.getGenericParameterTypes(); | |||
| String xclass = ts[0].toString(); | |||
| Object result = cellEntity.getValue(); | |||
| result = hanlderSuffix(entity.getSuffix(), result); | |||
| result = replaceValue(entity.getReplace(), result); | |||
| result = hanlderValue(dataHanlder, object, result, titleString); | |||
| return getValueByType(xclass, result, entity); | |||
| } | |||
| /** | |||
| * 把后缀删除掉 | |||
| * @param result | |||
| * @param suffix | |||
| * @return | |||
| */ | |||
| private Object hanlderSuffix(String suffix, Object result) { | |||
| if (StringUtils.isNotEmpty(suffix) && result != null | |||
| && result.toString().endsWith(suffix)) { | |||
| String temp = result.toString(); | |||
| return temp.substring(0, temp.length() - suffix.length()); | |||
| } | |||
| return result; | |||
| } | |||
| /** | |||
| * 根据返回类型获取返回值 | |||
| * | |||
| * @param xclass | |||
| * @param result | |||
| * @param entity | |||
| * @return | |||
| */ | |||
| private Object getValueByType(String xclass, Object result, ExcelImportEntity entity) { | |||
| try { | |||
| //过滤空和空字符串,如果基本类型null会在上层抛出,这里就不处理了 | |||
| if (result == null || StringUtils.isBlank(result.toString())) { | |||
| return null; | |||
| } | |||
| if ("class java.util.Date".equals(xclass)) { | |||
| return result; | |||
| } | |||
| if ("class java.lang.Boolean".equals(xclass) || "boolean".equals(xclass)) { | |||
| return Boolean.valueOf(String.valueOf(result)); | |||
| } | |||
| if ("class java.lang.Double".equals(xclass) || "double".equals(xclass)) { | |||
| return Double.valueOf(String.valueOf(result)); | |||
| } | |||
| if ("class java.lang.Long".equals(xclass) || "long".equals(xclass)) { | |||
| try { | |||
| return Long.valueOf(String.valueOf(result)); | |||
| } catch (Exception e) { | |||
| //格式错误的时候,就用double,然后获取Int值 | |||
| return Double.valueOf(String.valueOf(result)).longValue(); | |||
| } | |||
| } | |||
| if ("class java.lang.Float".equals(xclass) || "float".equals(xclass)) { | |||
| return Float.valueOf(String.valueOf(result)); | |||
| } | |||
| if ("class java.lang.Integer".equals(xclass) || "int".equals(xclass)) { | |||
| try { | |||
| return Integer.valueOf(String.valueOf(result)); | |||
| } catch (Exception e) { | |||
| //格式错误的时候,就用double,然后获取Int值 | |||
| return Double.valueOf(String.valueOf(result)).intValue(); | |||
| } | |||
| } | |||
| if ("class java.math.BigDecimal".equals(xclass)) { | |||
| return new BigDecimal(String.valueOf(result)); | |||
| } | |||
| if ("class java.lang.String".equals(xclass)) { | |||
| //针对String 类型,但是Excel获取的数据却不是String,比如Double类型,防止科学计数法 | |||
| if (result instanceof String) { | |||
| return result; | |||
| } | |||
| // double类型防止科学计数法 | |||
| if (result instanceof Double) { | |||
| return PoiPublicUtil.doubleToString((Double) result); | |||
| } | |||
| return String.valueOf(result); | |||
| } | |||
| return result; | |||
| } catch (Exception e) { | |||
| LOGGER.error(e.getMessage(), e); | |||
| throw new ExcelImportException(ExcelImportEnum.GET_VALUE_ERROR); | |||
| } | |||
| } | |||
| /** | |||
| * 调用处理接口处理值 | |||
| * | |||
| * @param dataHanlder | |||
| * @param object | |||
| * @param result | |||
| * @param titleString | |||
| * @return | |||
| */ | |||
| @SuppressWarnings({"unchecked", "rawtypes"}) | |||
| private Object hanlderValue(IExcelDataHandler dataHanlder, Object object, Object result, | |||
| String titleString) { | |||
| if (dataHanlder == null || dataHanlder.getNeedHandlerFields() == null | |||
| || dataHanlder.getNeedHandlerFields().length == 0) { | |||
| return result; | |||
| } | |||
| if (hanlderList == null) { | |||
| hanlderList = Arrays.asList(dataHanlder.getNeedHandlerFields()); | |||
| } | |||
| if (hanlderList.contains(titleString)) { | |||
| return dataHanlder.importHandler(object, titleString, result); | |||
| } | |||
| return result; | |||
| } | |||
| /** | |||
| * 替换值 | |||
| * | |||
| * @param replace | |||
| * @param result | |||
| * @return | |||
| */ | |||
| private Object replaceValue(String[] replace, Object result) { | |||
| if (replace != null && replace.length > 0) { | |||
| String temp = String.valueOf(result); | |||
| String[] tempArr; | |||
| for (int i = 0; i < replace.length; i++) { | |||
| tempArr = replace[i].split("_"); | |||
| if (temp.equals(tempArr[0])) { | |||
| return tempArr[1]; | |||
| } | |||
| } | |||
| } | |||
| return result; | |||
| } | |||
| /** | |||
| * Copyright 2013-2015 JueYue (qrb.jueyue@gmail.com) | |||
| * | |||
| * Licensed under the Apache License, Version 2.0 (the "License"); | |||
| * you may not use this file except in compliance with the License. | |||
| * You may obtain a copy of the License at | |||
| * | |||
| * http://www.apache.org/licenses/LICENSE-2.0 | |||
| * | |||
| * Unless required by applicable law or agreed to in writing, software | |||
| * distributed under the License is distributed on an "AS IS" BASIS, | |||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
| * See the License for the specific language governing permissions and | |||
| * limitations under the License. | |||
| */ | |||
| package cn.afterturn.easypoi.excel.imports; | |||
| import java.lang.reflect.Method; | |||
| import java.lang.reflect.Type; | |||
| import java.math.BigDecimal; | |||
| import java.sql.Time; | |||
| import java.sql.Timestamp; | |||
| import java.text.ParseException; | |||
| import java.text.SimpleDateFormat; | |||
| import java.util.Arrays; | |||
| import java.util.Date; | |||
| import java.util.List; | |||
| import java.util.Map; | |||
| import org.apache.commons.lang3.StringUtils; | |||
| import org.apache.poi.ss.usermodel.Cell; | |||
| import org.apache.poi.ss.usermodel.CellType; | |||
| import org.apache.poi.ss.usermodel.DateUtil; | |||
| import org.slf4j.Logger; | |||
| import org.slf4j.LoggerFactory; | |||
| import cn.afterturn.easypoi.excel.entity.params.ExcelImportEntity; | |||
| import cn.afterturn.easypoi.excel.entity.sax.SaxReadCellEntity; | |||
| import cn.afterturn.easypoi.exception.excel.ExcelImportException; | |||
| import cn.afterturn.easypoi.exception.excel.enums.ExcelImportEnum; | |||
| import cn.afterturn.easypoi.handler.inter.IExcelDataHandler; | |||
| import cn.afterturn.easypoi.util.PoiPublicUtil; | |||
| /** | |||
| * Cell 取值服务 | |||
| * 判断类型处理数据 1.判断Excel中的类型 2.根据replace替换值 3.handler处理数据 4.判断返回类型转化数据返回 | |||
| * | |||
| * @author JueYue | |||
| * 2014年6月26日 下午10:42:28 | |||
| */ | |||
| public class CellValueService { | |||
| private static final Logger LOGGER = LoggerFactory.getLogger(CellValueService.class); | |||
| private List<String> hanlderList = null; | |||
| /** | |||
| * 获取单元格内的值 | |||
| * | |||
| * @param cell | |||
| * @param entity | |||
| * @return | |||
| */ | |||
| private Object getCellValue(String xclass, Cell cell, ExcelImportEntity entity) { | |||
| if (cell == null) { | |||
| return ""; | |||
| } | |||
| Object result = null; | |||
| if ("class java.util.Date".equals(xclass) || "class java.sql.Date".equals(xclass) | |||
| || ("class java.sql.Time").equals(xclass) | |||
| || ("class java.sql.Timestamp").equals(xclass)) { | |||
| /* | |||
| if (Cell.CELL_TYPE_NUMERIC == cell.getCellType()) { | |||
| // 日期格式 | |||
| result = cell.getDateCellValue(); | |||
| } else { | |||
| cell.setCellType(Cell.CELL_TYPE_STRING); | |||
| result = getDateData(entity, cell.getStringCellValue()); | |||
| }*/ | |||
| //FIX: 单元格yyyyMMdd数字时候使用 cell.getDateCellValue() 解析出的日期错误 | |||
| if (Cell.CELL_TYPE_NUMERIC == cell.getCellType() && DateUtil.isCellDateFormatted(cell)) { | |||
| result = DateUtil.getJavaDate(cell.getNumericCellValue()); | |||
| } else { | |||
| cell.setCellType(CellType.STRING); | |||
| result = getDateData(entity, cell.getStringCellValue()); | |||
| } | |||
| if (("class java.sql.Date").equals(xclass)) { | |||
| result = new java.sql.Date(((Date) result).getTime()); | |||
| } | |||
| if (("class java.sql.Time").equals(xclass)) { | |||
| result = new Time(((Date) result).getTime()); | |||
| } | |||
| if (("class java.sql.Timestamp").equals(xclass)) { | |||
| result = new Timestamp(((Date) result).getTime()); | |||
| } | |||
| } else if (Cell.CELL_TYPE_NUMERIC == cell.getCellType() && DateUtil.isCellDateFormatted(cell)) { | |||
| result = DateUtil.getJavaDate(cell.getNumericCellValue()); | |||
| } else { | |||
| switch (cell.getCellType()) { | |||
| case Cell.CELL_TYPE_STRING: | |||
| result = cell.getRichStringCellValue() == null ? "" | |||
| : cell.getRichStringCellValue().getString(); | |||
| break; | |||
| case Cell.CELL_TYPE_NUMERIC: | |||
| if (DateUtil.isCellDateFormatted(cell)) { | |||
| if ("class java.lang.String".equals(xclass)) { | |||
| result = formateDate(entity, cell.getDateCellValue()); | |||
| } | |||
| } else { | |||
| result = readNumericCell(cell); | |||
| } | |||
| break; | |||
| case Cell.CELL_TYPE_BOOLEAN: | |||
| result = Boolean.toString(cell.getBooleanCellValue()); | |||
| break; | |||
| case Cell.CELL_TYPE_BLANK: | |||
| break; | |||
| case Cell.CELL_TYPE_ERROR: | |||
| break; | |||
| case Cell.CELL_TYPE_FORMULA: | |||
| try { | |||
| result = readNumericCell(cell); | |||
| } catch (Exception e1) { | |||
| try { | |||
| result = cell.getRichStringCellValue() == null ? "" | |||
| : cell.getRichStringCellValue().getString(); | |||
| } catch (Exception e2) { | |||
| throw new RuntimeException("获取公式类型的单元格失败", e2); | |||
| } | |||
| } | |||
| break; | |||
| default: | |||
| break; | |||
| } | |||
| } | |||
| return result; | |||
| } | |||
| private Object readNumericCell(Cell cell) { | |||
| Object result = null; | |||
| double value = cell.getNumericCellValue(); | |||
| if (((int) value) == value) { | |||
| result = (int) value; | |||
| } else { | |||
| result = value; | |||
| } | |||
| return result; | |||
| } | |||
| /** | |||
| * 获取日期类型数据 | |||
| * | |||
| * @author JueYue | |||
| * 2013年11月26日 | |||
| * @param entity | |||
| * @param value | |||
| * @return | |||
| */ | |||
| private Date getDateData(ExcelImportEntity entity, String value) { | |||
| if (StringUtils.isNotEmpty(entity.getFormat()) && StringUtils.isNotEmpty(value)) { | |||
| SimpleDateFormat format = new SimpleDateFormat(entity.getFormat()); | |||
| try { | |||
| return format.parse(value); | |||
| } catch (ParseException e) { | |||
| LOGGER.error("时间格式化失败,格式化:{},值:{}", entity.getFormat(), value); | |||
| throw new ExcelImportException(ExcelImportEnum.GET_VALUE_ERROR); | |||
| } | |||
| } | |||
| return null; | |||
| } | |||
| private String formateDate(ExcelImportEntity entity, Date value) { | |||
| if (StringUtils.isNotEmpty(entity.getFormat()) && value != null) { | |||
| SimpleDateFormat format = new SimpleDateFormat(entity.getFormat()); | |||
| return format.format(value); | |||
| } | |||
| return null; | |||
| } | |||
| /** | |||
| * 获取cell的值 | |||
| * | |||
| * @param object | |||
| * @param excelParams | |||
| * @param cell | |||
| * @param titleString | |||
| */ | |||
| public Object getValue(IExcelDataHandler<?> dataHanlder, Object object, Cell cell, | |||
| Map<String, ExcelImportEntity> excelParams, | |||
| String titleString) throws Exception { | |||
| ExcelImportEntity entity = excelParams.get(titleString); | |||
| String xclass = "class java.lang.Object"; | |||
| if (!(object instanceof Map)) { | |||
| Method setMethod = entity.getMethods() != null && entity.getMethods().size() > 0 | |||
| ? entity.getMethods().get(entity.getMethods().size() - 1) : entity.getMethod(); | |||
| Type[] ts = setMethod.getGenericParameterTypes(); | |||
| xclass = ts[0].toString(); | |||
| } | |||
| Object result = getCellValue(xclass, cell, entity); | |||
| if (entity != null) { | |||
| result = hanlderSuffix(entity.getSuffix(), result); | |||
| result = replaceValue(entity.getReplace(), result); | |||
| } | |||
| result = hanlderValue(dataHanlder, object, result, titleString); | |||
| return getValueByType(xclass, result, entity); | |||
| } | |||
| /** | |||
| * 获取cell值 | |||
| * @param dataHanlder | |||
| * @param object | |||
| * @param cellEntity | |||
| * @param excelParams | |||
| * @param titleString | |||
| * @return | |||
| */ | |||
| public Object getValue(IExcelDataHandler<?> dataHanlder, Object object, | |||
| SaxReadCellEntity cellEntity, Map<String, ExcelImportEntity> excelParams, | |||
| String titleString) { | |||
| ExcelImportEntity entity = excelParams.get(titleString); | |||
| Method setMethod = entity.getMethods() != null && entity.getMethods().size() > 0 | |||
| ? entity.getMethods().get(entity.getMethods().size() - 1) : entity.getMethod(); | |||
| Type[] ts = setMethod.getGenericParameterTypes(); | |||
| String xclass = ts[0].toString(); | |||
| Object result = cellEntity.getValue(); | |||
| result = hanlderSuffix(entity.getSuffix(), result); | |||
| result = replaceValue(entity.getReplace(), result); | |||
| result = hanlderValue(dataHanlder, object, result, titleString); | |||
| return getValueByType(xclass, result, entity); | |||
| } | |||
| /** | |||
| * 把后缀删除掉 | |||
| * @param result | |||
| * @param suffix | |||
| * @return | |||
| */ | |||
| private Object hanlderSuffix(String suffix, Object result) { | |||
| if (StringUtils.isNotEmpty(suffix) && result != null | |||
| && result.toString().endsWith(suffix)) { | |||
| String temp = result.toString(); | |||
| return temp.substring(0, temp.length() - suffix.length()); | |||
| } | |||
| return result; | |||
| } | |||
| /** | |||
| * 根据返回类型获取返回值 | |||
| * | |||
| * @param xclass | |||
| * @param result | |||
| * @param entity | |||
| * @return | |||
| */ | |||
| private Object getValueByType(String xclass, Object result, ExcelImportEntity entity) { | |||
| try { | |||
| //过滤空和空字符串,如果基本类型null会在上层抛出,这里就不处理了 | |||
| if (result == null || StringUtils.isBlank(result.toString())) { | |||
| return null; | |||
| } | |||
| if ("class java.util.Date".equals(xclass)) { | |||
| return result; | |||
| } | |||
| if ("class java.lang.Boolean".equals(xclass) || "boolean".equals(xclass)) { | |||
| return Boolean.valueOf(String.valueOf(result)); | |||
| } | |||
| if ("class java.lang.Double".equals(xclass) || "double".equals(xclass)) { | |||
| return Double.valueOf(String.valueOf(result)); | |||
| } | |||
| if ("class java.lang.Long".equals(xclass) || "long".equals(xclass)) { | |||
| try { | |||
| return Long.valueOf(String.valueOf(result)); | |||
| } catch (Exception e) { | |||
| //格式错误的时候,就用double,然后获取Int值 | |||
| return Double.valueOf(String.valueOf(result)).longValue(); | |||
| } | |||
| } | |||
| if ("class java.lang.Float".equals(xclass) || "float".equals(xclass)) { | |||
| return Float.valueOf(String.valueOf(result)); | |||
| } | |||
| if ("class java.lang.Integer".equals(xclass) || "int".equals(xclass)) { | |||
| try { | |||
| return Integer.valueOf(String.valueOf(result)); | |||
| } catch (Exception e) { | |||
| //格式错误的时候,就用double,然后获取Int值 | |||
| return Double.valueOf(String.valueOf(result)).intValue(); | |||
| } | |||
| } | |||
| if ("class java.math.BigDecimal".equals(xclass)) { | |||
| return new BigDecimal(String.valueOf(result)); | |||
| } | |||
| if ("class java.lang.String".equals(xclass)) { | |||
| //针对String 类型,但是Excel获取的数据却不是String,比如Double类型,防止科学计数法 | |||
| if (result instanceof String) { | |||
| return result; | |||
| } | |||
| // double类型防止科学计数法 | |||
| if (result instanceof Double) { | |||
| return PoiPublicUtil.doubleToString((Double) result); | |||
| } | |||
| return String.valueOf(result); | |||
| } | |||
| return result; | |||
| } catch (Exception e) { | |||
| LOGGER.error(e.getMessage(), e); | |||
| throw new ExcelImportException(ExcelImportEnum.GET_VALUE_ERROR); | |||
| } | |||
| } | |||
| /** | |||
| * 调用处理接口处理值 | |||
| * | |||
| * @param dataHanlder | |||
| * @param object | |||
| * @param result | |||
| * @param titleString | |||
| * @return | |||
| */ | |||
| @SuppressWarnings({"unchecked", "rawtypes"}) | |||
| private Object hanlderValue(IExcelDataHandler dataHanlder, Object object, Object result, | |||
| String titleString) { | |||
| if (dataHanlder == null || dataHanlder.getNeedHandlerFields() == null | |||
| || dataHanlder.getNeedHandlerFields().length == 0) { | |||
| return result; | |||
| } | |||
| if (hanlderList == null) { | |||
| hanlderList = Arrays.asList(dataHanlder.getNeedHandlerFields()); | |||
| } | |||
| if (hanlderList.contains(titleString)) { | |||
| return dataHanlder.importHandler(object, titleString, result); | |||
| } | |||
| return result; | |||
| } | |||
| /** | |||
| * 替换值 | |||
| * | |||
| * @param replace | |||
| * @param result | |||
| * @return | |||
| */ | |||
| private Object replaceValue(String[] replace, Object result) { | |||
| if (replace != null && replace.length > 0) { | |||
| String temp = String.valueOf(result); | |||
| String[] tempArr; | |||
| for (int i = 0; i < replace.length; i++) { | |||
| tempArr = replace[i].split("_"); | |||
| if (temp.equals(tempArr[0])) { | |||
| return tempArr[1]; | |||
| } | |||
| } | |||
| } | |||
| return result; | |||
| } | |||
| } | |||
| @@ -33,7 +33,7 @@ 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.sax.SaxReadCellEntity; | |||
| import cn.afterturn.easypoi.excel.imports.CellValueServer; | |||
| import cn.afterturn.easypoi.excel.imports.CellValueService; | |||
| import cn.afterturn.easypoi.excel.imports.base.ImportBaseService; | |||
| import cn.afterturn.easypoi.exception.excel.ExcelImportException; | |||
| import cn.afterturn.easypoi.handler.inter.IExcelReadRowHanlder; | |||
| @@ -67,7 +67,7 @@ public class SaxRowRead extends ImportBaseService implements ISaxRowRead { | |||
| private String targetId; | |||
| private CellValueServer cellValueServer; | |||
| private CellValueService cellValueServer; | |||
| private IExcelReadRowHanlder hanlder; | |||
| @@ -75,7 +75,7 @@ public class SaxRowRead extends ImportBaseService implements ISaxRowRead { | |||
| list = Lists.newArrayList(); | |||
| this.params = params; | |||
| this.pojoClass = pojoClass; | |||
| cellValueServer = new CellValueServer(); | |||
| cellValueServer = new CellValueService(); | |||
| this.hanlder = hanlder; | |||
| initParams(pojoClass, params); | |||
| } | |||
| @@ -41,7 +41,7 @@ import com.itextpdf.text.pdf.PdfWriter; | |||
| import cn.afterturn.easypoi.cache.ImageCache; | |||
| import cn.afterturn.easypoi.excel.annotation.ExcelTarget; | |||
| import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity; | |||
| import cn.afterturn.easypoi.excel.export.base.ExportCommonServer; | |||
| import cn.afterturn.easypoi.excel.export.base.ExportCommonService; | |||
| import cn.afterturn.easypoi.pdf.entity.PdfExportParams; | |||
| import cn.afterturn.easypoi.pdf.styler.IPdfExportStyler; | |||
| import cn.afterturn.easypoi.pdf.styler.PdfExportStylerDefaultImpl; | |||
| @@ -52,7 +52,7 @@ import cn.afterturn.easypoi.util.PoiPublicUtil; | |||
| * @author JueYue | |||
| * 2015年10月6日 下午8:21:08 | |||
| */ | |||
| public class PdfExportServer extends ExportCommonServer { | |||
| public class PdfExportServer extends ExportCommonService { | |||
| private static final Logger LOGGER = LoggerFactory.getLogger(PdfExportServer.class); | |||
| @@ -33,7 +33,7 @@ import org.slf4j.LoggerFactory; | |||
| import cn.afterturn.easypoi.excel.annotation.ExcelTarget; | |||
| import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity; | |||
| import cn.afterturn.easypoi.excel.export.base.ExportCommonServer; | |||
| import cn.afterturn.easypoi.excel.export.base.ExportCommonService; | |||
| import cn.afterturn.easypoi.exception.excel.ExcelExportException; | |||
| import cn.afterturn.easypoi.exception.excel.enums.ExcelExportEnum; | |||
| import cn.afterturn.easypoi.exception.word.WordExportException; | |||
| @@ -47,7 +47,7 @@ import cn.afterturn.easypoi.word.entity.params.ExcelListEntity; | |||
| * @author JueYue | |||
| * 2014年8月9日 下午10:30:57 | |||
| */ | |||
| public class ExcelEntityParse extends ExportCommonServer { | |||
| public class ExcelEntityParse extends ExportCommonService { | |||
| private static final Logger LOGGER = LoggerFactory.getLogger(ExcelEntityParse.class); | |||
| @@ -30,7 +30,7 @@ import org.springframework.stereotype.Controller; | |||
| import cn.afterturn.easypoi.entity.vo.NormalExcelConstants; | |||
| import cn.afterturn.easypoi.excel.ExcelExportUtil; | |||
| import cn.afterturn.easypoi.excel.entity.ExportParams; | |||
| import cn.afterturn.easypoi.excel.export.ExcelExportServer; | |||
| import cn.afterturn.easypoi.excel.export.ExcelExportService; | |||
| /** | |||
| * @author JueYue on 14-3-8. Excel 生成解析器,减少用户操作 | |||
| @@ -59,7 +59,7 @@ public class EasypoiSingleExcelView extends MiniAbstractExcelView { | |||
| .get(NormalExcelConstants.CLASS), | |||
| (Collection<?>) list.get(0).get(NormalExcelConstants.DATA_LIST)); | |||
| for (int i = 1; i < list.size(); i++) { | |||
| new ExcelExportServer().createSheet(workbook, | |||
| new ExcelExportService().createSheet(workbook, | |||
| (ExportParams) list.get(i).get(NormalExcelConstants.PARAMS), (Class<?>) list | |||
| .get(i).get(NormalExcelConstants.CLASS), | |||
| (Collection<?>) list.get(i).get(NormalExcelConstants.DATA_LIST)); | |||