| @@ -7,7 +7,7 @@ import com.google.common.cache.CacheLoader; | |||||
| import com.google.common.cache.LoadingCache; | import com.google.common.cache.LoadingCache; | ||||
| import cn.afterturn.easypoi.excel.entity.ExcelToHtmlParams; | import cn.afterturn.easypoi.excel.entity.ExcelToHtmlParams; | ||||
| import cn.afterturn.easypoi.excel.html.ExcelToHtmlServer; | |||||
| import cn.afterturn.easypoi.excel.html.ExcelToHtmlService; | |||||
| /** | /** | ||||
| * Excel 转变成为Html 的缓存 | * Excel 转变成为Html 的缓存 | ||||
| @@ -23,7 +23,7 @@ public class HtmlCache { | |||||
| .build(new CacheLoader<ExcelToHtmlParams, String>() { | .build(new CacheLoader<ExcelToHtmlParams, String>() { | ||||
| @Override | @Override | ||||
| public String load(ExcelToHtmlParams params) throws Exception { | 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); | fileis = ClassLoader.getSystemResourceAsStream(url); | ||||
| if (fileis == null) { | if (fileis == null) { | ||||
| //最后再拿想对文件路径 | |||||
| //最后再拿相对文件路径 | |||||
| String path = PoiPublicUtil.getWebRootPath(url); | String path = PoiPublicUtil.getWebRootPath(url); | ||||
| fileis = new FileInputStream(path); | fileis = new FileInputStream(path); | ||||
| } | } | ||||
| @@ -62,8 +62,6 @@ public class FileLoaderImpl implements IFileLoader { | |||||
| } | } | ||||
| baos.flush(); | baos.flush(); | ||||
| return baos.toByteArray(); | return baos.toByteArray(); | ||||
| } catch (FileNotFoundException e) { | |||||
| LOGGER.error(e.getMessage(), e); | |||||
| } catch (IOException e) { | } catch (IOException e) { | ||||
| LOGGER.error(e.getMessage(), e); | LOGGER.error(e.getMessage(), e); | ||||
| } finally { | } 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.TemplateExportParams; | ||||
| import cn.afterturn.easypoi.excel.entity.enmus.ExcelType; | import cn.afterturn.easypoi.excel.entity.enmus.ExcelType; | ||||
| import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity; | 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; | import cn.afterturn.easypoi.excel.export.template.ExcelExportOfTemplateUtil; | ||||
| /** | /** | ||||
| @@ -54,15 +54,15 @@ public class ExcelExportUtil { | |||||
| */ | */ | ||||
| public static Workbook exportBigExcel(ExportParams entity, Class<?> pojoClass, | public static Workbook exportBigExcel(ExportParams entity, Class<?> pojoClass, | ||||
| Collection<?> dataSet) { | 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() { | public static void closeExportBigExcel() { | ||||
| ExcelBatchExportServer batachServer = ExcelBatchExportServer.getExcelBatchExportServer(null, | |||||
| ExcelBatchExportService batchService = ExcelBatchExportService.getExcelBatchExportService(null, | |||||
| null); | null); | ||||
| batachServer.closeExportBigExcel(); | |||||
| batchService.closeExportBigExcel(); | |||||
| } | } | ||||
| /** | /** | ||||
| @@ -76,7 +76,7 @@ public class ExcelExportUtil { | |||||
| public static Workbook exportExcel(ExportParams entity, Class<?> pojoClass, | public static Workbook exportExcel(ExportParams entity, Class<?> pojoClass, | ||||
| Collection<?> dataSet) { | Collection<?> dataSet) { | ||||
| Workbook workbook = getWorkbook(entity.getType(),dataSet.size()); | Workbook workbook = getWorkbook(entity.getType(),dataSet.size()); | ||||
| new ExcelExportServer().createSheet(workbook, entity, pojoClass, dataSet); | |||||
| new ExcelExportService().createSheet(workbook, entity, pojoClass, dataSet); | |||||
| return workbook; | return workbook; | ||||
| } | } | ||||
| @@ -102,7 +102,7 @@ public class ExcelExportUtil { | |||||
| public static Workbook exportExcel(ExportParams entity, List<ExcelExportEntity> entityList, | public static Workbook exportExcel(ExportParams entity, List<ExcelExportEntity> entityList, | ||||
| Collection<? extends Map<?, ?>> dataSet) { | Collection<? extends Map<?, ?>> dataSet) { | ||||
| Workbook workbook = getWorkbook(entity.getType(),dataSet.size());; | Workbook workbook = getWorkbook(entity.getType(),dataSet.size());; | ||||
| new ExcelExportServer().createSheetForMap(workbook, entity, entityList, dataSet); | |||||
| new ExcelExportService().createSheetForMap(workbook, entity, entityList, dataSet); | |||||
| return workbook; | return workbook; | ||||
| } | } | ||||
| @@ -117,8 +117,8 @@ public class ExcelExportUtil { | |||||
| public static Workbook exportExcel(List<Map<String, Object>> list, ExcelType type) { | public static Workbook exportExcel(List<Map<String, Object>> list, ExcelType type) { | ||||
| Workbook workbook = getWorkbook(type,0); | Workbook workbook = getWorkbook(type,0); | ||||
| for (Map<String, Object> map : list) { | 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")); | (Class<?>) map.get("entity"), (Collection<?>) map.get("data")); | ||||
| } | } | ||||
| return workbook; | return workbook; | ||||
| @@ -26,7 +26,7 @@ import org.slf4j.LoggerFactory; | |||||
| import cn.afterturn.easypoi.excel.entity.ImportParams; | import cn.afterturn.easypoi.excel.entity.ImportParams; | ||||
| import cn.afterturn.easypoi.excel.entity.result.ExcelImportResult; | 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.SaxReadExcel; | ||||
| import cn.afterturn.easypoi.excel.imports.sax.parse.ISaxRowRead; | import cn.afterturn.easypoi.excel.imports.sax.parse.ISaxRowRead; | ||||
| import cn.afterturn.easypoi.exception.excel.ExcelImportException; | import cn.afterturn.easypoi.exception.excel.ExcelImportException; | ||||
| @@ -59,7 +59,7 @@ public class ExcelImportUtil { | |||||
| FileInputStream in = null; | FileInputStream in = null; | ||||
| try { | try { | ||||
| in = new FileInputStream(file); | in = new FileInputStream(file); | ||||
| return new ExcelImportServer().importExcelByIs(in, pojoClass, params).getList(); | |||||
| return new ExcelImportService().importExcelByIs(in, pojoClass, params).getList(); | |||||
| } catch (ExcelImportException e) { | } catch (ExcelImportException e) { | ||||
| throw new ExcelImportException(e.getType(), e); | throw new ExcelImportException(e.getType(), e); | ||||
| } catch (Exception e) { | } catch (Exception e) { | ||||
| @@ -81,7 +81,7 @@ public class ExcelImportUtil { | |||||
| */ | */ | ||||
| public static <T> List<T> importExcel(InputStream inputstream, Class<?> pojoClass, | public static <T> List<T> importExcel(InputStream inputstream, Class<?> pojoClass, | ||||
| ImportParams params) throws Exception { | 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, | public static <T> ExcelImportResult<T> importExcelMore(InputStream inputstream, | ||||
| Class<?> pojoClass, | Class<?> pojoClass, | ||||
| ImportParams params) throws Exception { | 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; | FileInputStream in = null; | ||||
| try { | try { | ||||
| in = new FileInputStream(file); | in = new FileInputStream(file); | ||||
| return new ExcelImportServer().importExcelByIs(in, pojoClass, params); | |||||
| return new ExcelImportService().importExcelByIs(in, pojoClass, params); | |||||
| } catch (ExcelImportException e) { | } catch (ExcelImportException e) { | ||||
| throw new ExcelImportException(e.getType(), e); | throw new ExcelImportException(e.getType(), e); | ||||
| } catch (Exception e) { | } catch (Exception e) { | ||||
| @@ -11,7 +11,7 @@ import java.io.InputStream; | |||||
| import cn.afterturn.easypoi.cache.HtmlCache; | import cn.afterturn.easypoi.cache.HtmlCache; | ||||
| import cn.afterturn.easypoi.excel.entity.ExcelToHtmlParams; | import cn.afterturn.easypoi.excel.entity.ExcelToHtmlParams; | ||||
| import cn.afterturn.easypoi.excel.entity.enmus.ExcelType; | 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.ExcelExportException; | ||||
| import cn.afterturn.easypoi.exception.excel.enums.ExcelExportEnum; | import cn.afterturn.easypoi.exception.excel.enums.ExcelExportEnum; | ||||
| @@ -65,7 +65,7 @@ public class ExcelXorHtmlUtil { | |||||
| } else { | } else { | ||||
| workbook = new XSSFWorkbook(); | workbook = new XSSFWorkbook(); | ||||
| } | } | ||||
| new HtmlToExcelServer().createSheet(html, workbook); | |||||
| new HtmlToExcelService().createSheet(html, workbook); | |||||
| return 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 | * @author JueYue 2014年6月17日 下午6:15:13 | ||||
| */ | */ | ||||
| @SuppressWarnings("unchecked") | @SuppressWarnings("unchecked") | ||||
| public abstract class BaseExportServer extends ExportCommonServer { | |||||
| public abstract class BaseExportService extends ExportCommonService { | |||||
| private int currentIndex = 0; | private int currentIndex = 0; | ||||
| @@ -29,7 +29,6 @@ import java.util.HashMap; | |||||
| import java.util.Iterator; | import java.util.Iterator; | ||||
| import java.util.List; | import java.util.List; | ||||
| import java.util.Map; | import java.util.Map; | ||||
| import java.util.Set; | |||||
| import org.apache.commons.lang3.StringUtils; | import org.apache.commons.lang3.StringUtils; | ||||
| import org.apache.commons.lang3.builder.ReflectionToStringBuilder; | 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 | * @author JueYue 2014年8月9日 下午11:01:32 | ||||
| */ | */ | ||||
| @SuppressWarnings("rawtypes") | @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; | 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.enmus.ExcelType; | ||||
| import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity; | import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity; | ||||
| import cn.afterturn.easypoi.excel.entity.params.ExcelForEachParams; | 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.styler.IExcelExportStyler; | ||||
| import cn.afterturn.easypoi.excel.export.template.TemplateSumHanlder.TemplateSumEntity; | import cn.afterturn.easypoi.excel.export.template.TemplateSumHanlder.TemplateSumEntity; | ||||
| import cn.afterturn.easypoi.excel.html.helper.MergedRegionHelper; | import cn.afterturn.easypoi.excel.html.helper.MergedRegionHelper; | ||||
| @@ -64,7 +64,7 @@ import cn.afterturn.easypoi.util.PoiSheetUtility; | |||||
| * 2013-10-17 | * 2013-10-17 | ||||
| * @version 1.0 | * @version 1.0 | ||||
| */ | */ | ||||
| public final class ExcelExportOfTemplateUtil extends BaseExportServer { | |||||
| public final class ExcelExportOfTemplateUtil extends BaseExportService { | |||||
| private static final Logger LOGGER = LoggerFactory | private static final Logger LOGGER = LoggerFactory | ||||
| .getLogger(ExcelExportOfTemplateUtil.class); | .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.ExcelCollectionParams; | ||||
| import cn.afterturn.easypoi.excel.entity.params.ExcelImportEntity; | import cn.afterturn.easypoi.excel.entity.params.ExcelImportEntity; | ||||
| import cn.afterturn.easypoi.excel.entity.sax.SaxReadCellEntity; | 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.excel.imports.base.ImportBaseService; | ||||
| import cn.afterturn.easypoi.exception.excel.ExcelImportException; | import cn.afterturn.easypoi.exception.excel.ExcelImportException; | ||||
| import cn.afterturn.easypoi.handler.inter.IExcelReadRowHanlder; | import cn.afterturn.easypoi.handler.inter.IExcelReadRowHanlder; | ||||
| @@ -67,7 +67,7 @@ public class SaxRowRead extends ImportBaseService implements ISaxRowRead { | |||||
| private String targetId; | private String targetId; | ||||
| private CellValueServer cellValueServer; | |||||
| private CellValueService cellValueServer; | |||||
| private IExcelReadRowHanlder hanlder; | private IExcelReadRowHanlder hanlder; | ||||
| @@ -75,7 +75,7 @@ public class SaxRowRead extends ImportBaseService implements ISaxRowRead { | |||||
| list = Lists.newArrayList(); | list = Lists.newArrayList(); | ||||
| this.params = params; | this.params = params; | ||||
| this.pojoClass = pojoClass; | this.pojoClass = pojoClass; | ||||
| cellValueServer = new CellValueServer(); | |||||
| cellValueServer = new CellValueService(); | |||||
| this.hanlder = hanlder; | this.hanlder = hanlder; | ||||
| initParams(pojoClass, params); | initParams(pojoClass, params); | ||||
| } | } | ||||
| @@ -41,7 +41,7 @@ import com.itextpdf.text.pdf.PdfWriter; | |||||
| import cn.afterturn.easypoi.cache.ImageCache; | import cn.afterturn.easypoi.cache.ImageCache; | ||||
| import cn.afterturn.easypoi.excel.annotation.ExcelTarget; | import cn.afterturn.easypoi.excel.annotation.ExcelTarget; | ||||
| import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity; | 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.entity.PdfExportParams; | ||||
| import cn.afterturn.easypoi.pdf.styler.IPdfExportStyler; | import cn.afterturn.easypoi.pdf.styler.IPdfExportStyler; | ||||
| import cn.afterturn.easypoi.pdf.styler.PdfExportStylerDefaultImpl; | import cn.afterturn.easypoi.pdf.styler.PdfExportStylerDefaultImpl; | ||||
| @@ -52,7 +52,7 @@ import cn.afterturn.easypoi.util.PoiPublicUtil; | |||||
| * @author JueYue | * @author JueYue | ||||
| * 2015年10月6日 下午8:21:08 | * 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); | 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.annotation.ExcelTarget; | ||||
| import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity; | 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.ExcelExportException; | ||||
| import cn.afterturn.easypoi.exception.excel.enums.ExcelExportEnum; | import cn.afterturn.easypoi.exception.excel.enums.ExcelExportEnum; | ||||
| import cn.afterturn.easypoi.exception.word.WordExportException; | import cn.afterturn.easypoi.exception.word.WordExportException; | ||||
| @@ -47,7 +47,7 @@ import cn.afterturn.easypoi.word.entity.params.ExcelListEntity; | |||||
| * @author JueYue | * @author JueYue | ||||
| * 2014年8月9日 下午10:30:57 | * 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); | 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.entity.vo.NormalExcelConstants; | ||||
| import cn.afterturn.easypoi.excel.ExcelExportUtil; | import cn.afterturn.easypoi.excel.ExcelExportUtil; | ||||
| import cn.afterturn.easypoi.excel.entity.ExportParams; | 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 生成解析器,减少用户操作 | * @author JueYue on 14-3-8. Excel 生成解析器,减少用户操作 | ||||
| @@ -59,7 +59,7 @@ public class EasypoiSingleExcelView extends MiniAbstractExcelView { | |||||
| .get(NormalExcelConstants.CLASS), | .get(NormalExcelConstants.CLASS), | ||||
| (Collection<?>) list.get(0).get(NormalExcelConstants.DATA_LIST)); | (Collection<?>) list.get(0).get(NormalExcelConstants.DATA_LIST)); | ||||
| for (int i = 1; i < list.size(); i++) { | 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 | (ExportParams) list.get(i).get(NormalExcelConstants.PARAMS), (Class<?>) list | ||||
| .get(i).get(NormalExcelConstants.CLASS), | .get(i).get(NormalExcelConstants.CLASS), | ||||
| (Collection<?>) list.get(i).get(NormalExcelConstants.DATA_LIST)); | (Collection<?>) list.get(i).get(NormalExcelConstants.DATA_LIST)); | ||||