mirror of
http://git.pig4cloud.com/pig/pigx.git
synced 2026-11-08 04:39:00 +08:00
✨ 添加新特性。pigxAutoPoi 导入导出公共核心包
This commit is contained in:
1 parent
c56b9d9fcf
commit
bb4a6285d5
99 files changed
+9494
No files matched your search
@@ -0,0 +1,86 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>pigx-common</artifactId>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<version>3.0.0</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>pigx-common-autopoi</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<description>pigx AutoPoi 导入导出公共核心包</description>
|
||||
|
||||
<properties>
|
||||
<java.version>1.8</java.version>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
|
||||
<xerces.version>2.9.1</xerces.version>
|
||||
<guava.version>20.0</guava.version>
|
||||
<commons-lang.version>3.2.1</commons-lang.version>
|
||||
<slf4j.version>1.7.16</slf4j.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<!--server-api-->
|
||||
<dependency>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>javax.servlet-api</artifactId>
|
||||
</dependency>
|
||||
<!--mybatis-->
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-boot-starter</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- poi -->
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi-ooxml</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi-ooxml-schemas</artifactId>
|
||||
</dependency>
|
||||
<!-- Sax 读入的时候使用 -->
|
||||
<dependency>
|
||||
<groupId>xerces</groupId>
|
||||
<artifactId>xercesImpl</artifactId>
|
||||
<version>${xerces.version}</version>
|
||||
</dependency>
|
||||
<!-- Word 时候用到 -->
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi-scratchpad</artifactId>
|
||||
<version>${poi.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- google 工具类 -->
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>${guava.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-lang3</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!--spring -->
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-webmvc</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
package com.pig4cloud.pigx.common.core.util;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
* 应用上下文工具
|
||||
*/
|
||||
public class ApplicationContextUtil implements ApplicationContextAware {
|
||||
|
||||
private static ApplicationContext context;
|
||||
|
||||
|
||||
public void setApplicationContext(ApplicationContext context)
|
||||
throws BeansException {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
public static ApplicationContext getContext() {
|
||||
return context;
|
||||
}
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
package com.pig4cloud.pigx.common.dict.service;
|
||||
|
||||
|
||||
/**
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
* 查询数据字典
|
||||
*/
|
||||
public interface AutoPoiDictServiceI{
|
||||
/**
|
||||
* 查询数据字典
|
||||
* @param dicTable
|
||||
* @param dicCode
|
||||
* @param dicText
|
||||
* @return
|
||||
*/
|
||||
String[] queryDict(String dicTable, String dicCode, String dicText);
|
||||
|
||||
}
|
||||
Vendored
+67
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
package com.pig4cloud.pigx.common.poi.cache;
|
||||
|
||||
import com.pig4cloud.pigx.common.poi.cache.manager.POICacheManager;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
|
||||
import org.apache.poi.ss.usermodel.Workbook;
|
||||
import org.apache.poi.ss.usermodel.WorkbookFactory;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
* Excel类型的缓存
|
||||
*/
|
||||
@Slf4j
|
||||
public final class ExcelCache {
|
||||
|
||||
public static Workbook getWorkbook(String url, Integer[] sheetNums, boolean needAll) {
|
||||
InputStream is = null;
|
||||
List<Integer> sheetList = Arrays.asList(sheetNums);
|
||||
try {
|
||||
is = POICacheManager.getFile(url);
|
||||
Workbook wb = WorkbookFactory.create(is);
|
||||
// 删除其他的sheet
|
||||
if (!needAll) {
|
||||
for (int i = wb.getNumberOfSheets() - 1; i >= 0; i--) {
|
||||
if (!sheetList.contains(i)) {
|
||||
wb.removeSheetAt(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
return wb;
|
||||
} catch (InvalidFormatException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
} finally {
|
||||
try {
|
||||
is.close();
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
Vendored
+52
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
package com.pig4cloud.pigx.common.poi.cache;
|
||||
|
||||
import com.pig4cloud.pigx.common.poi.cache.manager.POICacheManager;
|
||||
import com.pig4cloud.pigx.common.poi.word.entity.MyXWPFDocument;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
* word 缓存中心
|
||||
*/
|
||||
@Slf4j
|
||||
public class WordCache {
|
||||
|
||||
public static MyXWPFDocument getXWPFDocumen(String url) {
|
||||
InputStream is = null;
|
||||
try {
|
||||
is = POICacheManager.getFile(url);
|
||||
MyXWPFDocument doc = new MyXWPFDocument(is);
|
||||
return doc;
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
} finally {
|
||||
try {
|
||||
is.close();
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
package com.pig4cloud.pigx.common.poi.cache.manager;
|
||||
|
||||
import com.pig4cloud.pigx.common.poi.util.PoiPublicUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
* 文件加载类,根据路径加载指定文件
|
||||
*/
|
||||
@Slf4j
|
||||
class FileLoade {
|
||||
|
||||
public byte[] getFile(String url) {
|
||||
FileInputStream fileis = null;
|
||||
ByteArrayOutputStream baos = null;
|
||||
try {
|
||||
// 先用绝对路径查询,再查询相对路径
|
||||
try {
|
||||
fileis = new FileInputStream(url);
|
||||
} catch (FileNotFoundException e) {
|
||||
String path = PoiPublicUtil.getWebRootPath(url);
|
||||
fileis = new FileInputStream(path);
|
||||
}
|
||||
baos = new ByteArrayOutputStream();
|
||||
byte[] buffer = new byte[1024];
|
||||
int len;
|
||||
while ((len = fileis.read(buffer)) > -1) {
|
||||
baos.write(buffer, 0, len);
|
||||
}
|
||||
baos.flush();
|
||||
return baos.toByteArray();
|
||||
} catch (FileNotFoundException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
} catch (IOException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
} finally {
|
||||
try {
|
||||
if (fileis != null)
|
||||
fileis.close();
|
||||
if (fileis != null)
|
||||
baos.close();
|
||||
} catch (IOException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
log.error(fileis + "这个路径文件没有找到,请查询");
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
package com.pig4cloud.pigx.common.poi.cache.manager;
|
||||
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
* 缓存管理
|
||||
*/
|
||||
@Slf4j
|
||||
public final class POICacheManager {
|
||||
|
||||
private static LoadingCache<String, byte[]> loadingCache;
|
||||
|
||||
static {
|
||||
loadingCache = CacheBuilder.newBuilder().expireAfterWrite(7, TimeUnit.DAYS).maximumSize(50).build(new CacheLoader<String, byte[]>() {
|
||||
@Override
|
||||
public byte[] load(String url) throws Exception {
|
||||
return new FileLoade().getFile(url);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static InputStream getFile(String id) {
|
||||
try {
|
||||
// 复杂数据,防止操作原数据
|
||||
byte[] result = Arrays.copyOf(loadingCache.get(id), loadingCache.get(id).length);
|
||||
return new ByteArrayInputStream(result);
|
||||
} catch (ExecutionException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
Vendored
+9
@@ -0,0 +1,9 @@
|
||||
/**
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
* 对POI用到的模板进行缓存,进行统一管理,缓存工具暂时使用guava(脱离配置文件)
|
||||
* 缓存方式统一为byte[] 屏蔽文件类型的差异
|
||||
* 缓存获取方式,URL或者URL+index(EXcel的)
|
||||
*/
|
||||
package com.pig4cloud.pigx.common.poi.cache;
|
||||
+114
@@ -0,0 +1,114 @@
|
||||
package com.pig4cloud.pigx.common.poi.excel;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
import org.apache.poi.ss.usermodel.Workbook;
|
||||
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
import com.pig4cloud.pigx.common.poi.excel.entity.ExportParams;
|
||||
import com.pig4cloud.pigx.common.poi.excel.entity.TemplateExportParams;
|
||||
import com.pig4cloud.pigx.common.poi.excel.entity.enmus.ExcelType;
|
||||
import com.pig4cloud.pigx.common.poi.excel.entity.params.ExcelExportEntity;
|
||||
import com.pig4cloud.pigx.common.poi.excel.export.ExcelExportServer;
|
||||
import com.pig4cloud.pigx.common.poi.excel.export.template.ExcelExportOfTemplateUtil;
|
||||
|
||||
/**
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
* excel 导出工具类
|
||||
*/
|
||||
public final class ExcelExportUtil {
|
||||
|
||||
private ExcelExportUtil() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据Entity创建对应的Excel
|
||||
*
|
||||
* @param entity 表格标题属性
|
||||
* @param pojoClass Excel对象Class
|
||||
* @param dataSet Excel对象数据List
|
||||
*/
|
||||
public static Workbook exportExcel(ExportParams entity, Class<?> pojoClass, Collection<?> dataSet) {
|
||||
Workbook workbook;
|
||||
if (ExcelType.HSSF.equals(entity.getType())) {
|
||||
workbook = new HSSFWorkbook();
|
||||
} else if (dataSet.size() < 1000) {
|
||||
workbook = new XSSFWorkbook();
|
||||
} else {
|
||||
workbook = new SXSSFWorkbook();
|
||||
}
|
||||
new ExcelExportServer().createSheet(workbook, entity, pojoClass, dataSet);
|
||||
return workbook;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据Map创建对应的Excel
|
||||
*
|
||||
* @param entity 表格标题属性
|
||||
* @param dataSet Excel对象Class
|
||||
* @param entityList Excel对象数据List
|
||||
*/
|
||||
public static Workbook exportExcel(ExportParams entity, List<ExcelExportEntity> entityList, Collection<? extends Map<?, ?>> dataSet) {
|
||||
Workbook workbook;
|
||||
if (ExcelType.HSSF.equals(entity.getType())) {
|
||||
workbook = new HSSFWorkbook();
|
||||
} else if (dataSet.size() < 1000) {
|
||||
workbook = new XSSFWorkbook();
|
||||
} else {
|
||||
workbook = new SXSSFWorkbook();
|
||||
}
|
||||
new ExcelExportServer().createSheetForMap(workbook, entity, entityList, dataSet);
|
||||
return workbook;
|
||||
}
|
||||
|
||||
/**
|
||||
* 一个excel 创建多个sheet
|
||||
*
|
||||
* @param list 多个Map key title 对应表格Title key entity 对应表格对应实体 key data
|
||||
* Collection 数据
|
||||
* @return
|
||||
*/
|
||||
public static Workbook exportExcel(List<Map<String, Object>> list, String type) {
|
||||
Workbook workbook;
|
||||
if (ExcelType.HSSF.equals(type)) {
|
||||
workbook = new HSSFWorkbook();
|
||||
} else {
|
||||
workbook = new XSSFWorkbook();
|
||||
}
|
||||
for (Map<String, Object> map : list) {
|
||||
ExcelExportServer server = new ExcelExportServer();
|
||||
server.createSheet(workbook, (ExportParams) map.get("title"), (Class<?>) map.get("entity"), (Collection<?>) map.get("data"));
|
||||
}
|
||||
return workbook;
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出文件通过模板解析,不推荐这个了,推荐全部通过模板来执行处理
|
||||
*
|
||||
* @param params 导出参数类
|
||||
* @param pojoClass 对应实体
|
||||
* @param dataSet 实体集合
|
||||
* @param map 模板集合
|
||||
* @return
|
||||
*/
|
||||
public static Workbook exportExcel(TemplateExportParams params, Class<?> pojoClass, Collection<?> dataSet, Map<String, Object> map) {
|
||||
return new ExcelExportOfTemplateUtil().createExcleByTemplate(params, pojoClass, dataSet, map);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出文件通过模板解析只有模板,没有集合
|
||||
*
|
||||
* @param params 导出参数类
|
||||
* @param map 模板集合
|
||||
* @return
|
||||
*/
|
||||
public static Workbook exportExcel(TemplateExportParams params, Map<String, Object> map) {
|
||||
return new ExcelExportOfTemplateUtil().createExcleByTemplate(params, null, null, map);
|
||||
}
|
||||
|
||||
}
|
||||
+153
@@ -0,0 +1,153 @@
|
||||
package com.pig4cloud.pigx.common.poi.excel;
|
||||
|
||||
import com.pig4cloud.pigx.common.poi.excel.entity.ImportParams;
|
||||
import com.pig4cloud.pigx.common.poi.excel.entity.result.ExcelImportResult;
|
||||
import com.pig4cloud.pigx.common.poi.excel.imports.ExcelImportServer;
|
||||
import com.pig4cloud.pigx.common.poi.excel.imports.sax.SaxReadExcel;
|
||||
import com.pig4cloud.pigx.common.poi.excel.imports.sax.parse.ISaxRowRead;
|
||||
import com.pig4cloud.pigx.common.poi.handler.inter.IExcelReadRowHanlder;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Excel 导入工具
|
||||
*
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
*/
|
||||
@Slf4j
|
||||
@SuppressWarnings({"unchecked"})
|
||||
public final class ExcelImportUtil {
|
||||
|
||||
private ExcelImportUtil() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Excel 导入 数据源本地文件,不返回校验结果 导入 字 段类型 Integer,Long,Double,Date,String,Boolean
|
||||
*
|
||||
* @param file
|
||||
* @param pojoClass
|
||||
* @param params
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static <T> List<T> importExcel(File file, Class<?> pojoClass, ImportParams params) {
|
||||
FileInputStream in = null;
|
||||
List<T> result = null;
|
||||
try {
|
||||
in = new FileInputStream(file);
|
||||
result = new ExcelImportServer().importExcelByIs(in, pojoClass, params).getList();
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
} finally {
|
||||
try {
|
||||
in.close();
|
||||
} catch (IOException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Excel 导入 数据源IO流,不返回校验结果 导入 字段类型 Integer,Long,Double,Date,String,Boolean
|
||||
*
|
||||
* @param inputstream
|
||||
* @param pojoClass
|
||||
* @param params
|
||||
* @param <T>
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static <T> List<T> importExcel(InputStream inputstream, Class<?> pojoClass, ImportParams params) throws Exception {
|
||||
return new ExcelImportServer().importExcelByIs(inputstream, pojoClass, params).getList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Excel 导入 数据源IO流,返回校验结果 字段类型 Integer,Long,Double,Date,String,Boolean
|
||||
*
|
||||
* @param inputstream
|
||||
* @param pojoClass
|
||||
* @param params
|
||||
* @param <T>
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static <T> ExcelImportResult<T> importExcelVerify(InputStream inputstream, Class<?> pojoClass, ImportParams params) throws Exception {
|
||||
return new ExcelImportServer().importExcelByIs(inputstream, pojoClass, params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Excel 导入 数据源本地文件,返回校验结果 字段类型 Integer,Long,Double,Date,String,Boolean
|
||||
*
|
||||
* @param file
|
||||
* @param pojoClass
|
||||
* @param params
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static <T> ExcelImportResult<T> importExcelVerify(File file, Class<?> pojoClass, ImportParams params) {
|
||||
FileInputStream in = null;
|
||||
try {
|
||||
in = new FileInputStream(file);
|
||||
return new ExcelImportServer().importExcelByIs(in, pojoClass, params);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
} finally {
|
||||
try {
|
||||
in.close();
|
||||
} catch (IOException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Excel 通过SAX解析方法,适合大数据导入,不支持图片 导入 数据源IO流,不返回校验结果 导入 字段类型
|
||||
* Integer,Long,Double,Date,String,Boolean
|
||||
*
|
||||
* @param inputstream
|
||||
* @param pojoClass
|
||||
* @param params
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static <T> List<T> importExcelBySax(InputStream inputstream, Class<?> pojoClass, ImportParams params) {
|
||||
return new SaxReadExcel().readExcel(inputstream, pojoClass, params, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Excel 通过SAX解析方法,适合大数据导入,不支持图片 导入 数据源本地文件,不返回校验结果 导入 字 段类型
|
||||
* Integer,Long,Double,Date,String,Boolean
|
||||
*
|
||||
* @param inputstream
|
||||
* @param pojoClass
|
||||
* @param params
|
||||
* @param hanlder
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
public static void importExcelBySax(InputStream inputstream, Class<?> pojoClass, ImportParams params, IExcelReadRowHanlder hanlder) {
|
||||
new SaxReadExcel().readExcel(inputstream, pojoClass, params, null, hanlder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Excel 通过SAX解析方法,适合大数据导入,不支持图片 导入 数据源IO流,不返回校验结果 导入 字段类型
|
||||
* Integer,Long,Double,Date,String,Boolean
|
||||
*
|
||||
* @param inputstream
|
||||
* @param rowRead
|
||||
* @param <T>
|
||||
* @return
|
||||
*/
|
||||
public static <T> List<T> importExcelBySax(InputStream inputstream, ISaxRowRead rowRead) {
|
||||
return new SaxReadExcel().readExcel(inputstream, null, null, rowRead, null);
|
||||
}
|
||||
|
||||
}
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
package com.pig4cloud.pigx.common.poi.excel;
|
||||
|
||||
import com.pig4cloud.pigx.common.poi.excel.html.ExcelToHtmlServer;
|
||||
import org.apache.poi.ss.usermodel.Workbook;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
* Excel 变成界面
|
||||
*/
|
||||
public final class ExcelToHtmlUtil {
|
||||
|
||||
private ExcelToHtmlUtil() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换成为Table
|
||||
*
|
||||
* @param wb Excel
|
||||
* @return
|
||||
*/
|
||||
public static String toTableHtml(Workbook wb) {
|
||||
return new ExcelToHtmlServer(wb, false, 0).printPage();
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换成为Table
|
||||
*
|
||||
* @param wb Excel
|
||||
* @param sheetNum sheetNum
|
||||
* @return
|
||||
*/
|
||||
public static String toTableHtml(Workbook wb, int sheetNum) {
|
||||
return new ExcelToHtmlServer(wb, false, sheetNum).printPage();
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换成为完整界面
|
||||
*
|
||||
* @param wb Excel
|
||||
* @return
|
||||
*/
|
||||
public static String toAllHtml(Workbook wb) {
|
||||
return new ExcelToHtmlServer(wb, true, 0).printPage();
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换成为完整界面
|
||||
*
|
||||
* @param wb Excel
|
||||
* @param sheetNum sheetNum
|
||||
* @return
|
||||
*/
|
||||
public static String toAllHtml(Workbook wb, int sheetNum) {
|
||||
return new ExcelToHtmlServer(wb, true, sheetNum).printPage();
|
||||
}
|
||||
|
||||
}
|
||||
+205
@@ -0,0 +1,205 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
package com.pig4cloud.pigx.common.poi.excel.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
* Excel 导出基本注释
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
public @interface Excel {
|
||||
|
||||
/**
|
||||
* 导出时间设置,如果字段是Date类型则不需要设置 数据库如果是string 类型,这个需要设置这个数据库格式
|
||||
*
|
||||
* @return 返回类型: String
|
||||
*/
|
||||
String databaseFormat() default "yyyyMMddHHmmss";
|
||||
|
||||
/**
|
||||
* 导出的时间格式,以这个是否为空来判断是否需要格式化日期
|
||||
*
|
||||
* @return 返回类型: String
|
||||
*/
|
||||
String exportFormat() default "";
|
||||
|
||||
/**
|
||||
* 时间格式,相当于同时设置了exportFormat 和 importFormat
|
||||
*
|
||||
* @return 返回类型: String
|
||||
*/
|
||||
String format() default "";
|
||||
|
||||
/**
|
||||
* 导出时在excel中每个列的高度 单位为字符,一个汉字=2个字符
|
||||
*
|
||||
* @return 返回类型: double
|
||||
*/
|
||||
double height() default 10;
|
||||
|
||||
/**
|
||||
* 导出类型 1 从file读取 2 是从数据库中读取 默认是文件 同样导入也是一样的
|
||||
*
|
||||
* @return 返回类型: int
|
||||
*/
|
||||
int imageType() default 1;
|
||||
|
||||
/**
|
||||
* 导入的时间格式,以这个是否为空来判断是否需要格式化日期
|
||||
*
|
||||
* @return 返回类型: String
|
||||
*/
|
||||
String importFormat() default "";
|
||||
|
||||
/**
|
||||
* 文字后缀,如% 90 变成90%
|
||||
*
|
||||
* @return 返回类型: String
|
||||
*/
|
||||
String suffix() default "";
|
||||
|
||||
/**
|
||||
* 是否换行 即支持\n
|
||||
*
|
||||
* @return 返回类型: boolean
|
||||
*/
|
||||
boolean isWrap() default true;
|
||||
|
||||
/**
|
||||
* 合并单元格依赖关系,比如第二列合并是基于第一列 则{1}就可以了
|
||||
*
|
||||
* @return 返回类型: int[]
|
||||
*/
|
||||
int[] mergeRely() default {};
|
||||
|
||||
/**
|
||||
* 纵向合并内容相同的单元格
|
||||
*
|
||||
* @return 返回类型: boolean
|
||||
*/
|
||||
boolean mergeVertical() default false;
|
||||
|
||||
/**
|
||||
* 导出时,对应数据库的字段 主要是用户区分每个字段, 不能有annocation重名的 导出时的列名
|
||||
* 导出排序跟定义了annotation的字段的顺序有关 可以使用a_id,b_id来确实是否使用
|
||||
*
|
||||
* @return 返回类型: String
|
||||
*/
|
||||
String name();
|
||||
|
||||
/**
|
||||
* 是否需要纵向合并单元格(用于含有list中,单个的单元格,合并list创建的多个row)
|
||||
*
|
||||
* @return 返回类型: boolean
|
||||
*/
|
||||
boolean needMerge() default false;
|
||||
|
||||
/**
|
||||
* 展示到第几个可以使用a_id,b_id来确定不同排序
|
||||
*
|
||||
* @return 返回类型: String
|
||||
*/
|
||||
String orderNum() default "0";
|
||||
|
||||
/**
|
||||
* 值得替换 导出是{"男_1","女_0"} 导入反过来,所以只用写一个
|
||||
*
|
||||
* @return 返回类型: String[]
|
||||
*/
|
||||
String[] replace() default {};
|
||||
|
||||
/**
|
||||
* 导入路径,如果是图片可以填写,默认是upload/className/ IconEntity这个类对应的就是upload/Icon/
|
||||
*
|
||||
* @return 返回类型: String
|
||||
*/
|
||||
String savePath() default "upload";
|
||||
|
||||
/**
|
||||
* 导出类型 1 是文本 2 是图片,3是函数,4是数字 默认是文本
|
||||
*
|
||||
* @return 返回类型: int
|
||||
*/
|
||||
int type() default 1;
|
||||
|
||||
/**
|
||||
* 导出时在excel中每个列的宽 单位为字符,一个汉字=2个字符 如 以列名列内容中较合适的长度 例如姓名列6 【姓名一般三个字】
|
||||
* 性别列4【男女占1,但是列标题两个汉字】 限制1-255
|
||||
*
|
||||
* @return 返回类型: double
|
||||
*/
|
||||
double width() default 10;
|
||||
|
||||
/**
|
||||
* 是否自动统计数据,如果是统计,true的话在最后追加一行统计,把所有数据都和 这个处理会吞没异常,请注意这一点
|
||||
*
|
||||
* @return 返回类型: boolean
|
||||
*/
|
||||
boolean isStatistics() default false;
|
||||
|
||||
/**
|
||||
* 数据字典表
|
||||
*
|
||||
* @return 返回类型: String
|
||||
*/
|
||||
String dictTable() default "";
|
||||
|
||||
/**
|
||||
* 数据code
|
||||
*
|
||||
* @return 返回类型: String
|
||||
*/
|
||||
String dicCode() default "";
|
||||
|
||||
/**
|
||||
* 数据Text
|
||||
*
|
||||
* @return 返回类型: String
|
||||
*/
|
||||
String dicText() default "";
|
||||
|
||||
/**
|
||||
* 导入数据是否需要转化
|
||||
* 若是为true,则需要在pojo中加入 方法:convertset字段名(String text)
|
||||
*
|
||||
* @return 返回类型: boolean
|
||||
*/
|
||||
boolean importConvert() default false;
|
||||
|
||||
/**
|
||||
* 导出数据是否需要转化
|
||||
* 若是为true,则需要在pojo中加入方法:convertget字段名()
|
||||
*
|
||||
* @return 返回类型: boolean
|
||||
*/
|
||||
boolean exportConvert() default false;
|
||||
|
||||
/**
|
||||
* 值的替换是否支持替换多个(默认true,若数据库值本来就包含逗号则需要配置该值为false)
|
||||
*
|
||||
* @return 返回类型: boolean
|
||||
*/
|
||||
boolean multiReplace() default true;
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
package com.pig4cloud.pigx.common.poi.excel.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
* 导出的集合
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
public @interface ExcelCollection {
|
||||
|
||||
/**
|
||||
* 定义excel导出ID 来限定导出字段,处理一个类对应多个不同名称的情况
|
||||
*/
|
||||
String id() default "";
|
||||
|
||||
/**
|
||||
* 导出时,对应数据库的字段 主要是用户区分每个字段, 不能有annocation重名的 导出时的列名
|
||||
* 导出排序跟定义了annotation的字段的顺序有关 可以使用a_id,b_id来确实是否使用
|
||||
*/
|
||||
String name();
|
||||
|
||||
/**
|
||||
* 展示到第几个同样可以使用a_id,b_id
|
||||
*
|
||||
*/
|
||||
String orderNum() default "0";
|
||||
|
||||
/**
|
||||
* 创建时创建的类型 默认值是 arrayList
|
||||
*/
|
||||
Class<?> type() default ArrayList.class;
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
package com.pig4cloud.pigx.common.poi.excel.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
* 标记是不是导出excel 标记为实体类
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
public @interface ExcelEntity {
|
||||
|
||||
/**
|
||||
* 定义excel导出ID 来限定导出字段,处理一个类对应多个不同名称的情况
|
||||
*/
|
||||
String id() default "";
|
||||
|
||||
/**
|
||||
* 导出时,对应数据库的字段 主要是用户区分每个字段, 不能有annocation重名的 导出时的列名
|
||||
* 导出排序跟定义了annotation的字段的顺序有关 可以使用a_id,b_id来确实是否使用
|
||||
*/
|
||||
String name() default "";
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
package com.pig4cloud.pigx.common.poi.excel.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
* 标记为excel 创建实体忽略
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
public @interface ExcelIgnore {
|
||||
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
package com.pig4cloud.pigx.common.poi.excel.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
* excel 导出是用于标记id的
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ ElementType.TYPE })
|
||||
public @interface ExcelTarget {
|
||||
/**
|
||||
* 定义excel导出ID 来限定导出字段
|
||||
*/
|
||||
String value();
|
||||
}
|
||||
+96
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, lengleng All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: lengleng (wangiegie@gmail.com)
|
||||
*/
|
||||
package com.pig4cloud.pigx.common.poi.excel.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
* Excel 导入校验
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
public @interface ExcelVerify {
|
||||
/**
|
||||
* 接口校验
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
boolean interHandler() default false;
|
||||
|
||||
/**
|
||||
* 是电子邮件
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
boolean isEmail() default false;
|
||||
|
||||
/**
|
||||
* 是13位移动电话
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
boolean isMobile() default false;
|
||||
|
||||
/**
|
||||
* 是座机号码
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
boolean isTel() default false;
|
||||
|
||||
/**
|
||||
* 最大长度
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
int maxLength() default -1;
|
||||
|
||||
/**
|
||||
* 最小长度
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
int minLength() default -1;
|
||||
|
||||
/**
|
||||
* 不允许空
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
boolean notNull() default false;
|
||||
|
||||
/**
|
||||
* 正在表达式
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String regex() default "";
|
||||
|
||||
/**
|
||||
* 正在表达式,错误提示信息
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String regexTip() default "数据不符合规范";
|
||||
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
package com.pig4cloud.pigx.common.poi.excel.def;
|
||||
|
||||
/**
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
* 基础POI常量
|
||||
*/
|
||||
interface BasePOIConstants {
|
||||
|
||||
/**
|
||||
* 注解对象
|
||||
*/
|
||||
String CLASS = "entity";
|
||||
/**
|
||||
* 表格参数
|
||||
*/
|
||||
String PARAMS = "params";
|
||||
/**
|
||||
* 下载文件名称
|
||||
*/
|
||||
String FILE_NAME = "fileName";
|
||||
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
package com.pig4cloud.pigx.common.poi.excel.def;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
* 正常导出Excel
|
||||
*/
|
||||
public interface MapExcelConstants extends BasePOIConstants {
|
||||
/**
|
||||
* 单Sheet导出
|
||||
*/
|
||||
String PIGX_MAP_EXCEL_VIEW = "pigxMapExcelView";
|
||||
/**
|
||||
* Entity List
|
||||
*/
|
||||
String ENTITY_LIST = "data";
|
||||
/**
|
||||
* 数据列表
|
||||
*/
|
||||
String MAP_LIST = "mapList";
|
||||
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
package com.pig4cloud.pigx.common.poi.excel.def;
|
||||
|
||||
/**
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
* 正常导出Excel
|
||||
*/
|
||||
public interface NormalExcelConstants extends BasePOIConstants {
|
||||
/**
|
||||
* 单Sheet导出
|
||||
*/
|
||||
String PIGX_ENTITY_EXCEL_VIEW = "pigxEntityExcelView";
|
||||
/**
|
||||
* 数据列表
|
||||
*/
|
||||
String DATA_LIST = "data";
|
||||
/**
|
||||
* 多Sheet 对象
|
||||
*/
|
||||
String MAP_LIST = "mapList";
|
||||
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
package com.pig4cloud.pigx.common.poi.excel.def;
|
||||
|
||||
/**
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
* 模板Excel导出常量
|
||||
*/
|
||||
public interface TemplateExcelConstants extends BasePOIConstants {
|
||||
/**
|
||||
* 模板导出
|
||||
*/
|
||||
String PIGX_TEMPLATE_EXCEL_VIEW = "pigxTemplateExcelView";
|
||||
/**
|
||||
* 数据列表
|
||||
*/
|
||||
String LIST_DATA = "list";
|
||||
/**
|
||||
* 模板参数
|
||||
*/
|
||||
String MAP_DATA = "map";
|
||||
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
package com.pig4cloud.pigx.common.poi.excel.def;
|
||||
|
||||
/**
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
* Word 导出模板常量
|
||||
*/
|
||||
public interface TemplateWordConstants extends BasePOIConstants {
|
||||
/**
|
||||
* 模板导出
|
||||
*/
|
||||
String PIGX_TEMPLATE_WORD_VIEW = "pigxTemplateWordView";
|
||||
/**
|
||||
* 数据列表
|
||||
*/
|
||||
String URL = "url";
|
||||
/**
|
||||
* 模板参数
|
||||
*/
|
||||
String MAP_DATA = "map";
|
||||
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
package com.pig4cloud.pigx.common.poi.excel.entity;
|
||||
|
||||
import com.pig4cloud.pigx.common.poi.handler.inter.IExcelDataHandler;
|
||||
|
||||
/**
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
* 基础参数
|
||||
*/
|
||||
public class ExcelBaseParams {
|
||||
|
||||
/**
|
||||
* 数据处理接口,以此为主,replace,format都在这后面
|
||||
*/
|
||||
private IExcelDataHandler dataHanlder;
|
||||
|
||||
public IExcelDataHandler getDataHanlder() {
|
||||
return dataHanlder;
|
||||
}
|
||||
|
||||
public void setDataHanlder(IExcelDataHandler dataHanlder) {
|
||||
this.dataHanlder = dataHanlder;
|
||||
}
|
||||
|
||||
}
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
package com.pig4cloud.pigx.common.poi.excel.entity;
|
||||
|
||||
import lombok.Data;
|
||||
import org.apache.poi.hssf.util.HSSFColor;
|
||||
import com.pig4cloud.pigx.common.poi.excel.entity.enmus.ExcelType;
|
||||
import com.pig4cloud.pigx.common.poi.excel.export.styler.ExcelExportStylerDefaultImpl;
|
||||
|
||||
/**
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
* Excel 导出参数
|
||||
*/
|
||||
@Data
|
||||
public class ExportParams extends ExcelBaseParams {
|
||||
|
||||
/**
|
||||
* 表格名称
|
||||
*/
|
||||
private String title;
|
||||
|
||||
/**
|
||||
* 表格名称
|
||||
*/
|
||||
private short titleHeight = 10;
|
||||
|
||||
/**
|
||||
* 第二行名称
|
||||
*/
|
||||
private String secondTitle;
|
||||
|
||||
/**
|
||||
* 表格名称
|
||||
*/
|
||||
private short secondTitleHeight = 8;
|
||||
/**
|
||||
* sheetName
|
||||
*/
|
||||
private String sheetName;
|
||||
/**
|
||||
* 过滤的属性
|
||||
*/
|
||||
private String[] exclusions;
|
||||
/**
|
||||
* 是否添加需要需要
|
||||
*/
|
||||
private boolean addIndex;
|
||||
/**
|
||||
* 是否添加需要需要
|
||||
*/
|
||||
private String indexName = "序号";
|
||||
/**
|
||||
* 冰冻列
|
||||
*/
|
||||
private int freezeCol;
|
||||
/**
|
||||
* 表头颜色
|
||||
*/
|
||||
private short color = HSSFColor.WHITE.index;
|
||||
/**
|
||||
* 属性说明行的颜色 例如:HSSFColor.SKY_BLUE.index 默认
|
||||
*/
|
||||
private short headerColor = HSSFColor.SKY_BLUE.index;
|
||||
/**
|
||||
* Excel 导出版本
|
||||
*/
|
||||
private ExcelType type = ExcelType.HSSF;
|
||||
/**
|
||||
* Excel 导出style
|
||||
*/
|
||||
private Class<?> style = ExcelExportStylerDefaultImpl.class;
|
||||
/**
|
||||
* 是否创建表头
|
||||
*/
|
||||
private boolean isCreateHeadRows = true;
|
||||
|
||||
public ExportParams() {
|
||||
|
||||
}
|
||||
|
||||
public ExportParams(String title, String sheetName) {
|
||||
this.title = title;
|
||||
this.sheetName = sheetName;
|
||||
}
|
||||
|
||||
public ExportParams(String title, String sheetName, ExcelType type) {
|
||||
this.title = title;
|
||||
this.sheetName = sheetName;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public ExportParams(String title, String secondTitle, String sheetName) {
|
||||
this.title = title;
|
||||
this.secondTitle = secondTitle;
|
||||
this.sheetName = sheetName;
|
||||
}
|
||||
|
||||
public short getSecondTitleHeight() {
|
||||
return (short) (secondTitleHeight * 50);
|
||||
}
|
||||
|
||||
public short getTitleHeight() {
|
||||
return (short) (titleHeight * 50);
|
||||
}
|
||||
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
package com.pig4cloud.pigx.common.poi.excel.entity;
|
||||
|
||||
import com.pig4cloud.pigx.common.poi.handler.inter.IExcelVerifyHandler;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
* 导入参数设置
|
||||
*/
|
||||
@Data
|
||||
public class ImportParams extends ExcelBaseParams {
|
||||
/**
|
||||
* 表格标题行数,默认0
|
||||
*/
|
||||
private int titleRows = 0;
|
||||
/**
|
||||
* 表头行数,默认1
|
||||
*/
|
||||
private int headRows = 1;
|
||||
/**
|
||||
* 字段真正值和列标题之间的距离 默认0
|
||||
*/
|
||||
private int startRows = 0;
|
||||
/**
|
||||
* 主键设置,如何这个cell没有值,就跳过 或者认为这个是list的下面的值
|
||||
*/
|
||||
private int keyIndex = 0;
|
||||
/**
|
||||
* 上传表格需要读取的sheet 数量,默认为1
|
||||
*/
|
||||
private int sheetNum = 1;
|
||||
/**
|
||||
* 是否需要保存上传的Excel,默认为false
|
||||
*/
|
||||
private boolean needSave = false;
|
||||
/**
|
||||
* 保存上传的Excel目录,默认是 如 TestEntity这个类保存路径就是
|
||||
* upload/excelUpload/Test/yyyyMMddHHmss_***** 保存名称上传时间_五位随机数
|
||||
*/
|
||||
private String saveUrl = "upload/excelUpload";
|
||||
/**
|
||||
* 校验处理接口
|
||||
*/
|
||||
private IExcelVerifyHandler verifyHanlder;
|
||||
/**
|
||||
* 最后的无效行数
|
||||
*/
|
||||
private int lastOfInvalidRow = 0;
|
||||
|
||||
}
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
package com.pig4cloud.pigx.common.poi.excel.entity;
|
||||
|
||||
import com.pig4cloud.pigx.common.poi.excel.export.styler.ExcelExportStylerDefaultImpl;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
* 模板导出参数设置
|
||||
*/
|
||||
@Data
|
||||
public class TemplateExportParams extends ExcelBaseParams {
|
||||
|
||||
/**
|
||||
* 输出全部的sheet
|
||||
*/
|
||||
private boolean scanAllsheet = false;
|
||||
/**
|
||||
* 模板的路径
|
||||
*/
|
||||
private String templateUrl;
|
||||
|
||||
/**
|
||||
* 需要导出的第几个 sheetNum,默认是第0个
|
||||
*/
|
||||
private Integer[] sheetNum = new Integer[]{0};
|
||||
|
||||
/**
|
||||
* 这只sheetName 不填就使用原来的
|
||||
*/
|
||||
private String[] sheetName;
|
||||
|
||||
/**
|
||||
* 表格列标题行数,默认1
|
||||
*/
|
||||
private int headingRows = 1;
|
||||
|
||||
/**
|
||||
* 表格列标题开始行,默认1
|
||||
*/
|
||||
private int headingStartRow = 1;
|
||||
/**
|
||||
* 设置数据源的NUM
|
||||
*/
|
||||
private int dataSheetNum = 0;
|
||||
/**
|
||||
* Excel 导出style
|
||||
*/
|
||||
private Class<?> style = ExcelExportStylerDefaultImpl.class;
|
||||
/**
|
||||
* FOR EACH 用到的局部变量
|
||||
*/
|
||||
private String tempParams = "t";
|
||||
|
||||
/**
|
||||
* 默认构造器
|
||||
*/
|
||||
public TemplateExportParams() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造器
|
||||
*
|
||||
* @param templateUrl 模板路径
|
||||
* @param scanAllsheet 是否输出全部的sheet
|
||||
* @param sheetName sheet的名称,可不填
|
||||
*/
|
||||
public TemplateExportParams(String templateUrl, boolean scanAllsheet, String... sheetName) {
|
||||
this.templateUrl = templateUrl;
|
||||
this.scanAllsheet = scanAllsheet;
|
||||
if (sheetName != null && sheetName.length > 0) {
|
||||
this.sheetName = sheetName;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 构造器
|
||||
*
|
||||
* @param templateUrl 模板路径
|
||||
* @param sheetNum sheet 的位置,可不填
|
||||
*/
|
||||
public TemplateExportParams(String templateUrl, Integer... sheetNum) {
|
||||
this.templateUrl = templateUrl;
|
||||
if (sheetNum != null && sheetNum.length > 0) {
|
||||
this.sheetNum = sheetNum;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 单个sheet输出构造器
|
||||
*
|
||||
* @param templateUrl 模板路径
|
||||
* @param sheetName sheet的名称
|
||||
* @param sheetNum sheet的位置,可不填
|
||||
*/
|
||||
public TemplateExportParams(String templateUrl, String sheetName, Integer... sheetNum) {
|
||||
this.templateUrl = templateUrl;
|
||||
this.sheetName = new String[]{sheetName};
|
||||
if (sheetNum != null && sheetNum.length > 0) {
|
||||
this.sheetNum = sheetNum;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package com.pig4cloud.pigx.common.poi.excel.entity.enmus;
|
||||
|
||||
/**
|
||||
* Cell 值得类型
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
*/
|
||||
public enum CellValueType {
|
||||
|
||||
String, Number, Boolean, Date, TElement, Null, None;
|
||||
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
package com.pig4cloud.pigx.common.poi.excel.entity.enmus;
|
||||
|
||||
import com.pig4cloud.pigx.common.poi.excel.export.styler.ExcelExportStylerBorderImpl;
|
||||
import com.pig4cloud.pigx.common.poi.excel.export.styler.ExcelExportStylerColorImpl;
|
||||
import com.pig4cloud.pigx.common.poi.excel.export.styler.ExcelExportStylerDefaultImpl;
|
||||
|
||||
/**
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
* 插件提供的几个默认样式
|
||||
*/
|
||||
public enum ExcelStyleType {
|
||||
|
||||
NONE("默认样式", ExcelExportStylerDefaultImpl.class),
|
||||
BORDER("边框样式", ExcelExportStylerBorderImpl.class),
|
||||
COLOR("间隔行样式", ExcelExportStylerColorImpl.class);
|
||||
|
||||
private String name;
|
||||
private Class<?> clazz;
|
||||
|
||||
ExcelStyleType(String name, Class<?> clazz) {
|
||||
this.name = name;
|
||||
this.clazz = clazz;
|
||||
}
|
||||
|
||||
public Class<?> getClazz() {
|
||||
return clazz;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package com.pig4cloud.pigx.common.poi.excel.entity.enmus;
|
||||
|
||||
/**
|
||||
* Excel Type
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
*/
|
||||
public enum ExcelType {
|
||||
|
||||
HSSF, XSSF;
|
||||
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
package com.pig4cloud.pigx.common.poi.excel.entity.params;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
* Excel 导入导出基础对象类
|
||||
*/
|
||||
@Data
|
||||
public class ExcelBaseEntity {
|
||||
/**
|
||||
* 对应name
|
||||
*/
|
||||
protected String name;
|
||||
/**
|
||||
* 对应type
|
||||
*/
|
||||
private int type = 1;
|
||||
/**
|
||||
* 数据库格式
|
||||
*/
|
||||
private String databaseFormat;
|
||||
/**
|
||||
* 导出日期格式
|
||||
*/
|
||||
private String format;
|
||||
/**
|
||||
* 替换值表达式 :"男_1","女_0"
|
||||
*/
|
||||
private String[] replace;
|
||||
/**
|
||||
* 替换是否是替换多个值
|
||||
*/
|
||||
private boolean multiReplace;
|
||||
/**
|
||||
* set/get方法
|
||||
*/
|
||||
private Method method;
|
||||
/**
|
||||
* set/get方法
|
||||
*/
|
||||
private List<Method> methods;
|
||||
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
package com.pig4cloud.pigx.common.poi.excel.entity.params;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Excel 对于的 Collection
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
*/
|
||||
@Data
|
||||
public class ExcelCollectionParams {
|
||||
|
||||
/**
|
||||
* 集合对应的名称
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* Excel 列名称
|
||||
*/
|
||||
private String excelName;
|
||||
/**
|
||||
* 实体对象
|
||||
*/
|
||||
private Class<?> type;
|
||||
/**
|
||||
* 这个list下面的参数集合实体对象
|
||||
*/
|
||||
private Map<String, ExcelImportEntity> excelParams;
|
||||
|
||||
}
|
||||
+180
@@ -0,0 +1,180 @@
|
||||
package com.pig4cloud.pigx.common.poi.excel.entity.params;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* excel 导出工具类,对cell类型做映射
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
*/
|
||||
public class ExcelExportEntity extends ExcelBaseEntity implements Comparable<ExcelExportEntity> {
|
||||
|
||||
/**
|
||||
* 如果是MAP导出,这个是map的key
|
||||
*/
|
||||
private Object key;
|
||||
|
||||
private double width = 10;
|
||||
|
||||
private double height = 10;
|
||||
|
||||
/**
|
||||
* 图片的类型,1是文件,2是数据库
|
||||
*/
|
||||
private int exportImageType = 0;
|
||||
|
||||
/**
|
||||
* 排序顺序
|
||||
*/
|
||||
private int orderNum = 0;
|
||||
|
||||
/**
|
||||
* 是否支持换行
|
||||
*/
|
||||
private boolean isWrap;
|
||||
|
||||
/**
|
||||
* 是否需要合并
|
||||
*/
|
||||
private boolean needMerge;
|
||||
/**
|
||||
* 单元格纵向合并
|
||||
*/
|
||||
private boolean mergeVertical;
|
||||
/**
|
||||
* 合并依赖
|
||||
*/
|
||||
private int[] mergeRely;
|
||||
/**
|
||||
* 后缀
|
||||
*/
|
||||
private String suffix;
|
||||
/**
|
||||
* 统计
|
||||
*/
|
||||
private boolean isStatistics;
|
||||
|
||||
private List<ExcelExportEntity> list;
|
||||
|
||||
public ExcelExportEntity() {
|
||||
|
||||
}
|
||||
|
||||
public ExcelExportEntity(String name) {
|
||||
super.name = name;
|
||||
}
|
||||
|
||||
public ExcelExportEntity(String name, Object key) {
|
||||
super.name = name;
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public ExcelExportEntity(String name, Object key, int width) {
|
||||
super.name = name;
|
||||
this.width = width;
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public int getExportImageType() {
|
||||
return exportImageType;
|
||||
}
|
||||
|
||||
public double getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
public Object getKey() {
|
||||
return key;
|
||||
}
|
||||
|
||||
public List<ExcelExportEntity> getList() {
|
||||
return list;
|
||||
}
|
||||
|
||||
public int[] getMergeRely() {
|
||||
return mergeRely == null ? new int[0] : mergeRely;
|
||||
}
|
||||
|
||||
public int getOrderNum() {
|
||||
return orderNum;
|
||||
}
|
||||
|
||||
public double getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
public boolean isMergeVertical() {
|
||||
return mergeVertical;
|
||||
}
|
||||
|
||||
public boolean isNeedMerge() {
|
||||
return needMerge;
|
||||
}
|
||||
|
||||
public boolean isWrap() {
|
||||
return isWrap;
|
||||
}
|
||||
|
||||
public void setExportImageType(int exportImageType) {
|
||||
this.exportImageType = exportImageType;
|
||||
}
|
||||
|
||||
public void setHeight(double height) {
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
public void setKey(Object key) {
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public void setList(List<ExcelExportEntity> list) {
|
||||
this.list = list;
|
||||
}
|
||||
|
||||
public void setMergeRely(int[] mergeRely) {
|
||||
this.mergeRely = mergeRely;
|
||||
}
|
||||
|
||||
public void setMergeVertical(boolean mergeVertical) {
|
||||
this.mergeVertical = mergeVertical;
|
||||
}
|
||||
|
||||
public void setNeedMerge(boolean needMerge) {
|
||||
this.needMerge = needMerge;
|
||||
}
|
||||
|
||||
public void setOrderNum(int orderNum) {
|
||||
this.orderNum = orderNum;
|
||||
}
|
||||
|
||||
public void setWidth(double width) {
|
||||
this.width = width;
|
||||
}
|
||||
|
||||
public void setWrap(boolean isWrap) {
|
||||
this.isWrap = isWrap;
|
||||
}
|
||||
|
||||
public String getSuffix() {
|
||||
return suffix;
|
||||
}
|
||||
|
||||
public void setSuffix(String suffix) {
|
||||
this.suffix = suffix;
|
||||
}
|
||||
|
||||
public boolean isStatistics() {
|
||||
return isStatistics;
|
||||
}
|
||||
|
||||
public void setStatistics(boolean isStatistics) {
|
||||
this.isStatistics = isStatistics;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(ExcelExportEntity prev) {
|
||||
return this.getOrderNum() - prev.getOrderNum();
|
||||
}
|
||||
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
package com.pig4cloud.pigx.common.poi.excel.entity.params;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* excel 导入工具类,对cell类型做映射
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
*/
|
||||
@Data
|
||||
public class ExcelImportEntity extends ExcelBaseEntity {
|
||||
/**
|
||||
* 对应 Collection NAME
|
||||
*/
|
||||
private String collectionName;
|
||||
/**
|
||||
* 保存图片的地址
|
||||
*/
|
||||
private String saveUrl;
|
||||
/**
|
||||
* 保存图片的类型,1是文件,2是数据库
|
||||
*/
|
||||
private int saveType;
|
||||
/**
|
||||
* 对应exportType
|
||||
*/
|
||||
private String classType;
|
||||
/**
|
||||
* 校驗參數
|
||||
*/
|
||||
private ExcelVerifyEntity verify;
|
||||
/**
|
||||
* 后缀
|
||||
*/
|
||||
private String suffix;
|
||||
/**
|
||||
* list
|
||||
*/
|
||||
private List<ExcelImportEntity> list;
|
||||
|
||||
|
||||
}
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
package com.pig4cloud.pigx.common.poi.excel.entity.params;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.apache.poi.ss.usermodel.CellStyle;
|
||||
|
||||
/**
|
||||
* 模板便利是的参数
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
*/
|
||||
public class ExcelTemplateParams implements Serializable {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
/**
|
||||
* key
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 模板的cellStyle
|
||||
*/
|
||||
private CellStyle cellStyle;
|
||||
/**
|
||||
* 行高
|
||||
*/
|
||||
private short height;
|
||||
|
||||
public ExcelTemplateParams() {
|
||||
|
||||
}
|
||||
|
||||
public ExcelTemplateParams(String name, CellStyle cellStyle, short height) {
|
||||
this.name = name;
|
||||
this.cellStyle = cellStyle;
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public CellStyle getCellStyle() {
|
||||
return cellStyle;
|
||||
}
|
||||
|
||||
public void setCellStyle(CellStyle cellStyle) {
|
||||
this.cellStyle = cellStyle;
|
||||
}
|
||||
|
||||
public short getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
public void setHeight(short height) {
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
}
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
package com.pig4cloud.pigx.common.poi.excel.entity.params;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* Excel 校验对象
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
*/
|
||||
@Data
|
||||
public class ExcelVerifyEntity {
|
||||
|
||||
/**
|
||||
* 接口校验
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private boolean interHandler;
|
||||
|
||||
/**
|
||||
* 不允许空
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private boolean notNull;
|
||||
|
||||
/**
|
||||
* 是13位移动电话
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private boolean isMobile;
|
||||
/**
|
||||
* 是座机号码
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private boolean isTel;
|
||||
|
||||
/**
|
||||
* 是电子邮件
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private boolean isEmail;
|
||||
|
||||
/**
|
||||
* 最小长度
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private int minLength;
|
||||
|
||||
/**
|
||||
* 最大长度
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private int maxLength;
|
||||
|
||||
/**
|
||||
* 正在表达式
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private String regex;
|
||||
/**
|
||||
* 正在表达式,错误提示信息
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private String regexTip;
|
||||
|
||||
}
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
package com.pig4cloud.pigx.common.poi.excel.entity.params;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 合并单元格使用对象
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
*/
|
||||
public class MergeEntity {
|
||||
/**
|
||||
* 合并开始行
|
||||
*/
|
||||
private int startRow;
|
||||
/**
|
||||
* 合并结束行
|
||||
*/
|
||||
private int endRow;
|
||||
/**
|
||||
* 文字
|
||||
*/
|
||||
private String text;
|
||||
/**
|
||||
* 依赖关系文本
|
||||
*/
|
||||
private List<String> relyList;
|
||||
|
||||
public MergeEntity() {
|
||||
|
||||
}
|
||||
|
||||
public MergeEntity(String text, int startRow, int endRow) {
|
||||
this.text = text;
|
||||
this.endRow = endRow;
|
||||
this.startRow = startRow;
|
||||
}
|
||||
|
||||
public int getEndRow() {
|
||||
return endRow;
|
||||
}
|
||||
|
||||
public List<String> getRelyList() {
|
||||
return relyList;
|
||||
}
|
||||
|
||||
public int getStartRow() {
|
||||
return startRow;
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
public void setEndRow(int endRow) {
|
||||
this.endRow = endRow;
|
||||
}
|
||||
|
||||
public void setRelyList(List<String> relyList) {
|
||||
this.relyList = relyList;
|
||||
}
|
||||
|
||||
public void setStartRow(int startRow) {
|
||||
this.startRow = startRow;
|
||||
}
|
||||
|
||||
public void setText(String text) {
|
||||
this.text = text;
|
||||
}
|
||||
}
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
package com.pig4cloud.pigx.common.poi.excel.entity.result;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.poi.ss.usermodel.Workbook;
|
||||
|
||||
/**
|
||||
* 导入返回类
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
*/
|
||||
public class ExcelImportResult<T> {
|
||||
|
||||
/**
|
||||
* 结果集
|
||||
*/
|
||||
private List<T> list;
|
||||
|
||||
/**
|
||||
* 是否存在校验失败
|
||||
*/
|
||||
private boolean verfiyFail;
|
||||
|
||||
/**
|
||||
* 数据源
|
||||
*/
|
||||
private Workbook workbook;
|
||||
|
||||
public ExcelImportResult() {
|
||||
|
||||
}
|
||||
|
||||
public ExcelImportResult(List<T> list, boolean verfiyFail, Workbook workbook) {
|
||||
this.list = list;
|
||||
this.verfiyFail = verfiyFail;
|
||||
this.workbook = workbook;
|
||||
}
|
||||
|
||||
public List<T> getList() {
|
||||
return list;
|
||||
}
|
||||
|
||||
public Workbook getWorkbook() {
|
||||
return workbook;
|
||||
}
|
||||
|
||||
public boolean isVerfiyFail() {
|
||||
return verfiyFail;
|
||||
}
|
||||
|
||||
public void setList(List<T> list) {
|
||||
this.list = list;
|
||||
}
|
||||
|
||||
public void setVerfiyFail(boolean verfiyFail) {
|
||||
this.verfiyFail = verfiyFail;
|
||||
}
|
||||
|
||||
public void setWorkbook(Workbook workbook) {
|
||||
this.workbook = workbook;
|
||||
}
|
||||
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
package com.pig4cloud.pigx.common.poi.excel.entity.result;
|
||||
|
||||
/**
|
||||
* Excel导入处理返回结果
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
*/
|
||||
public class ExcelVerifyHanlderResult {
|
||||
/**
|
||||
* 是否正确
|
||||
*/
|
||||
private boolean success;
|
||||
/**
|
||||
* 错误信息
|
||||
*/
|
||||
private String msg;
|
||||
|
||||
public ExcelVerifyHanlderResult() {
|
||||
|
||||
}
|
||||
|
||||
public ExcelVerifyHanlderResult(boolean success) {
|
||||
this.success = success;
|
||||
}
|
||||
|
||||
public ExcelVerifyHanlderResult(boolean success, String msg) {
|
||||
this.success = success;
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
public String getMsg() {
|
||||
return msg;
|
||||
}
|
||||
|
||||
public boolean isSuccess() {
|
||||
return success;
|
||||
}
|
||||
|
||||
public void setMsg(String msg) {
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
public void setSuccess(boolean success) {
|
||||
this.success = success;
|
||||
}
|
||||
|
||||
}
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
package com.pig4cloud.pigx.common.poi.excel.entity.sax;
|
||||
|
||||
import com.pig4cloud.pigx.common.poi.excel.entity.enmus.CellValueType;
|
||||
|
||||
/**
|
||||
* Cell 对象
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
*/
|
||||
public class SaxReadCellEntity {
|
||||
/**
|
||||
* 值类型
|
||||
*/
|
||||
private CellValueType cellType;
|
||||
/**
|
||||
* 值
|
||||
*/
|
||||
private Object value;
|
||||
|
||||
public SaxReadCellEntity(CellValueType cellType, Object value) {
|
||||
this.cellType = cellType;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public CellValueType getCellType() {
|
||||
return cellType;
|
||||
}
|
||||
|
||||
public void setCellType(CellValueType cellType) {
|
||||
this.cellType = cellType;
|
||||
}
|
||||
|
||||
public Object getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(Object value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "[type=" + cellType.toString() + ",value=" + value + "]";
|
||||
}
|
||||
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
package com.pig4cloud.pigx.common.poi.excel.entity.vo;
|
||||
|
||||
/**
|
||||
* 基础常量
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
*/
|
||||
public interface PoiBaseConstants {
|
||||
/**
|
||||
* 字段属性对应方法
|
||||
*/
|
||||
String GET = "get";
|
||||
/**
|
||||
* 字段属性对应方法
|
||||
*/
|
||||
String SET = "set";
|
||||
/**
|
||||
* 字段属性对应方法
|
||||
*/
|
||||
String IS = "is";
|
||||
/**
|
||||
* 是否增加属性列
|
||||
*/
|
||||
String IS_ADD_INDEX = "isAddIndex";
|
||||
/**
|
||||
* 字段属性对应convert方法
|
||||
*/
|
||||
String CONVERT = "convert";
|
||||
|
||||
}
|
||||
+285
@@ -0,0 +1,285 @@
|
||||
package com.pig4cloud.pigx.common.poi.excel.export;
|
||||
|
||||
import com.pig4cloud.pigx.common.poi.excel.annotation.ExcelTarget;
|
||||
import com.pig4cloud.pigx.common.poi.excel.entity.ExportParams;
|
||||
import com.pig4cloud.pigx.common.poi.excel.entity.enmus.ExcelType;
|
||||
import com.pig4cloud.pigx.common.poi.excel.entity.params.ExcelExportEntity;
|
||||
import com.pig4cloud.pigx.common.poi.excel.entity.vo.PoiBaseConstants;
|
||||
import com.pig4cloud.pigx.common.poi.excel.export.base.ExcelExportBase;
|
||||
import com.pig4cloud.pigx.common.poi.excel.export.styler.IExcelExportStyler;
|
||||
import com.pig4cloud.pigx.common.poi.exception.excel.ExcelExportException;
|
||||
import com.pig4cloud.pigx.common.poi.exception.excel.enums.ExcelExportEnum;
|
||||
import com.pig4cloud.pigx.common.poi.util.PoiPublicUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.poi.ss.usermodel.*;
|
||||
import org.apache.poi.ss.util.CellRangeAddress;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
* Excel导出服务
|
||||
*/
|
||||
@Slf4j
|
||||
public class ExcelExportServer extends ExcelExportBase {
|
||||
|
||||
// 最大行数,超过自动多Sheet
|
||||
private int MAX_NUM = 60000;
|
||||
|
||||
private int createHeaderAndTitle(ExportParams entity, Sheet sheet, Workbook workbook, List<ExcelExportEntity> excelParams) {
|
||||
int rows = 0, feildWidth = getFieldWidth(excelParams);
|
||||
if (entity.getTitle() != null) {
|
||||
rows += createHeaderRow(entity, sheet, workbook, feildWidth);
|
||||
}
|
||||
rows += createTitleRow(entity, sheet, workbook, rows, excelParams);
|
||||
sheet.createFreezePane(0, rows, 0, rows);
|
||||
return rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建 表头改变
|
||||
*
|
||||
* @param entity
|
||||
* @param sheet
|
||||
* @param workbook
|
||||
* @param feildWidth
|
||||
*/
|
||||
public int createHeaderRow(ExportParams entity, Sheet sheet, Workbook workbook, int feildWidth) {
|
||||
Row row = sheet.createRow(0);
|
||||
row.setHeight(entity.getTitleHeight());
|
||||
createStringCell(row, 0, entity.getTitle(), getExcelExportStyler().getHeaderStyle(entity.getHeaderColor()), null);
|
||||
for (int i = 1; i <= feildWidth; i++) {
|
||||
createStringCell(row, i, "", getExcelExportStyler().getHeaderStyle(entity.getHeaderColor()), null);
|
||||
}
|
||||
sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, feildWidth));
|
||||
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 <= feildWidth; i++) {
|
||||
createStringCell(row, i, "", getExcelExportStyler().getHeaderStyle(entity.getHeaderColor()), null);
|
||||
}
|
||||
sheet.addMergedRegion(new CellRangeAddress(1, 1, 0, feildWidth));
|
||||
return 2;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
public void createSheet(Workbook workbook, ExportParams entity, Class<?> pojoClass, Collection<?> dataSet) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Excel export start ,class is {}", pojoClass);
|
||||
log.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);
|
||||
}
|
||||
super.type = entity.getType();
|
||||
if (type.equals(ExcelType.XSSF)) {
|
||||
MAX_NUM = 1000000;
|
||||
}
|
||||
Sheet sheet = null;
|
||||
try {
|
||||
sheet = workbook.createSheet(entity.getSheetName());
|
||||
} catch (Exception e) {
|
||||
// 重复遍历,出现了重名现象,创建非指定的名称Sheet
|
||||
sheet = workbook.createSheet();
|
||||
}
|
||||
try {
|
||||
dataHanlder = entity.getDataHanlder();
|
||||
if (dataHanlder != null) {
|
||||
needHanlderList = Arrays.asList(dataHanlder.getNeedHandlerFields());
|
||||
}
|
||||
// 创建表格样式 TODO 出错
|
||||
setExcelExportStyler((IExcelExportStyler) entity.getStyle().getConstructor(Workbook.class).newInstance(workbook));
|
||||
Drawing patriarch = sheet.createDrawingPatriarch();
|
||||
List<ExcelExportEntity> 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);
|
||||
sortAllParams(excelParams);
|
||||
int index = entity.isCreateHeadRows() ? createHeaderAndTitle(entity, sheet, workbook, excelParams) : 0;
|
||||
int titleHeight = index;
|
||||
setCellWith(excelParams, sheet);
|
||||
short rowHeight = 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;
|
||||
}
|
||||
mergeCells(sheet, excelParams, titleHeight);
|
||||
|
||||
if (entity.getFreezeCol() != 0) {
|
||||
sheet.createFreezePane(entity.getFreezeCol(), 0, entity.getFreezeCol(), 0);
|
||||
}
|
||||
|
||||
its = dataSet.iterator();
|
||||
for (int i = 0, le = tempList.size(); i < le; i++) {
|
||||
its.next();
|
||||
its.remove();
|
||||
}
|
||||
// 创建合计信息
|
||||
addStatisticsRow(getExcelExportStyler().getStyles(true, null), sheet);
|
||||
|
||||
// 发现还有剩余list 继续循环创建Sheet
|
||||
if (dataSet.size() > 0) {
|
||||
createSheet(workbook, entity, pojoClass, dataSet);
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
log.error(e.getMessage(), e);
|
||||
throw new ExcelExportException(ExcelExportEnum.EXPORT_ERROR, e.getCause());
|
||||
}
|
||||
}
|
||||
|
||||
public void createSheetForMap(Workbook workbook, ExportParams entity, List<ExcelExportEntity> entityList, Collection<? extends Map<?, ?>> dataSet) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.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;
|
||||
}
|
||||
Sheet sheet = null;
|
||||
try {
|
||||
sheet = workbook.createSheet(entity.getSheetName());
|
||||
} catch (Exception e) {
|
||||
// 重复遍历,出现了重名现象,创建非指定的名称Sheet
|
||||
sheet = workbook.createSheet();
|
||||
}
|
||||
try {
|
||||
dataHanlder = entity.getDataHanlder();
|
||||
if (dataHanlder != null) {
|
||||
needHanlderList = Arrays.asList(dataHanlder.getNeedHandlerFields());
|
||||
}
|
||||
// 创建表格样式
|
||||
setExcelExportStyler((IExcelExportStyler) entity.getStyle().getConstructor(Workbook.class).newInstance(workbook));
|
||||
Drawing patriarch = sheet.createDrawingPatriarch();
|
||||
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 = 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();
|
||||
}
|
||||
// 发现还有剩余list 继续循环创建Sheet
|
||||
if (dataSet.size() > 0) {
|
||||
createSheetForMap(workbook, entity, entityList, dataSet);
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
throw new ExcelExportException(ExcelExportEnum.EXPORT_ERROR, e.getCause());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建表头
|
||||
*
|
||||
* @param title
|
||||
* @param index
|
||||
*/
|
||||
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;
|
||||
CellStyle titleStyle = getExcelExportStyler().getTitleStyle(title.getColor());
|
||||
for (int i = 0, exportFieldTitleSize = excelParams.size(); i < exportFieldTitleSize; i++) {
|
||||
ExcelExportEntity entity = excelParams.get(i);
|
||||
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) {
|
||||
createStringCell(listRow, cellIndex, "", titleStyle, entity);
|
||||
sheet.addMergedRegion(new CellRangeAddress(index, index + 1, cellIndex, cellIndex));
|
||||
}
|
||||
cellIndex++;
|
||||
}
|
||||
return rows;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断表头是只有一行还是两行
|
||||
*
|
||||
* @param excelParams
|
||||
* @return
|
||||
*/
|
||||
private int getRowNums(List<ExcelExportEntity> excelParams) {
|
||||
for (int i = 0; i < excelParams.size(); i++) {
|
||||
if (excelParams.get(i).getList() != null && StringUtils.isNotBlank(excelParams.get(i).getName())) {
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
private ExcelExportEntity indexExcelEntity(ExportParams entity) {
|
||||
ExcelExportEntity exportEntity = new ExcelExportEntity();
|
||||
exportEntity.setOrderNum(0);
|
||||
exportEntity.setName(entity.getIndexName());
|
||||
exportEntity.setWidth(10);
|
||||
exportEntity.setFormat(PoiBaseConstants.IS_ADD_INDEX);
|
||||
return exportEntity;
|
||||
}
|
||||
|
||||
}
|
||||
+386
@@ -0,0 +1,386 @@
|
||||
package com.pig4cloud.pigx.common.poi.excel.export.base;
|
||||
|
||||
import com.pig4cloud.pigx.common.poi.excel.entity.enmus.ExcelType;
|
||||
import com.pig4cloud.pigx.common.poi.excel.entity.params.ExcelExportEntity;
|
||||
import com.pig4cloud.pigx.common.poi.excel.entity.vo.PoiBaseConstants;
|
||||
import com.pig4cloud.pigx.common.poi.excel.export.styler.IExcelExportStyler;
|
||||
import com.pig4cloud.pigx.common.poi.util.PoiMergeCellUtil;
|
||||
import com.pig4cloud.pigx.common.poi.util.PoiPublicUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.poi.hssf.usermodel.HSSFClientAnchor;
|
||||
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
|
||||
import org.apache.poi.ss.usermodel.*;
|
||||
import org.apache.poi.ss.util.CellRangeAddress;
|
||||
import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
|
||||
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
* 提供POI基础操作服务
|
||||
*/
|
||||
@Slf4j
|
||||
public abstract class ExcelExportBase extends ExportBase {
|
||||
|
||||
private int currentIndex = 0;
|
||||
|
||||
protected ExcelType type = ExcelType.HSSF;
|
||||
|
||||
private Map<Integer, Double> statistics = new HashMap<Integer, Double>();
|
||||
|
||||
private static final DecimalFormat DOUBLE_FORMAT = new DecimalFormat("######0.00");
|
||||
|
||||
private IExcelExportStyler excelExportStyler;
|
||||
|
||||
/**
|
||||
* 创建 最主要的 Cells
|
||||
*
|
||||
* @param patriarch
|
||||
* @param index
|
||||
* @param t
|
||||
* @param excelParams
|
||||
* @param sheet
|
||||
* @param workbook
|
||||
* @param rowHeight
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public int createCells(Drawing patriarch, int index, Object t, List<ExcelExportEntity> excelParams, Sheet sheet, Workbook workbook, short rowHeight) throws Exception {
|
||||
ExcelExportEntity entity;
|
||||
Row row = sheet.createRow(index);
|
||||
row.setHeight(rowHeight);
|
||||
int maxHeight = 1, cellNum = 0;
|
||||
int indexKey = createIndexCell(row, index, excelParams.get(0));
|
||||
cellNum += indexKey;
|
||||
for (int k = indexKey, paramSize = excelParams.size(); k < paramSize; k++) {
|
||||
entity = excelParams.get(k);
|
||||
if (entity.getList() != null) {
|
||||
Collection<?> list = getListCellValue(entity, t);
|
||||
int listC = 0;
|
||||
for (Object obj : list) {
|
||||
createListCells(patriarch, index + listC, cellNum, obj, entity.getList(), sheet, workbook);
|
||||
listC++;
|
||||
}
|
||||
cellNum += entity.getList().size();
|
||||
if (list != null && list.size() > maxHeight) {
|
||||
maxHeight = list.size();
|
||||
}
|
||||
} else {
|
||||
Object value = getCellValue(entity, t);
|
||||
if (entity.getType() == 1) {
|
||||
createStringCell(row, cellNum++, value == null ? "" : value.toString(), index % 2 == 0 ? getStyles(false, entity) : getStyles(true, entity), entity);
|
||||
} else if (entity.getType() == 4){
|
||||
createNumericCell(row, cellNum++, value == null ? "" : value.toString(), index % 2 == 0 ? getStyles(false, entity) : getStyles(true, entity), entity);
|
||||
} else {
|
||||
createImageCell(patriarch, entity, row, cellNum++, value == null ? "" : value.toString(), t);
|
||||
}
|
||||
}
|
||||
}
|
||||
// 合并需要合并的单元格
|
||||
cellNum = 0;
|
||||
for (int k = indexKey, paramSize = excelParams.size(); k < paramSize; k++) {
|
||||
entity = excelParams.get(k);
|
||||
if (entity.getList() != null) {
|
||||
cellNum += entity.getList().size();
|
||||
} else if (entity.isNeedMerge()) {
|
||||
for (int i = index + 1; i < index + maxHeight; i++) {
|
||||
sheet.getRow(i).createCell(cellNum);
|
||||
sheet.getRow(i).getCell(cellNum).setCellStyle(getStyles(false, entity));
|
||||
}
|
||||
sheet.addMergedRegion(new CellRangeAddress(index, index + maxHeight - 1, cellNum, cellNum));
|
||||
cellNum++;
|
||||
}
|
||||
}
|
||||
return maxHeight;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 图片类型的Cell
|
||||
*
|
||||
* @param patriarch
|
||||
* @param entity
|
||||
* @param row
|
||||
* @param i
|
||||
* @param imagePath
|
||||
* @param obj
|
||||
* @throws Exception
|
||||
*/
|
||||
public void createImageCell(Drawing patriarch, ExcelExportEntity entity, Row row, int i, String imagePath, Object obj) throws Exception {
|
||||
row.setHeight((short) (50 * entity.getHeight()));
|
||||
row.createCell(i);
|
||||
ClientAnchor anchor;
|
||||
if (type.equals(ExcelType.HSSF)) {
|
||||
anchor = new HSSFClientAnchor(0, 0, 0, 0, (short) i, row.getRowNum(), (short) (i + 1), row.getRowNum() + 1);
|
||||
} else {
|
||||
anchor = new XSSFClientAnchor(0, 0, 0, 0, (short) i, row.getRowNum(), (short) (i + 1), row.getRowNum() + 1);
|
||||
}
|
||||
|
||||
if (StringUtils.isEmpty(imagePath)) {
|
||||
return;
|
||||
}
|
||||
if (entity.getExportImageType() == 1) {
|
||||
ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream();
|
||||
BufferedImage bufferImg;
|
||||
try {
|
||||
String path = PoiPublicUtil.getWebRootPath(imagePath);
|
||||
log.debug("--- createImageCell getWebRootPath ----filePath--- "+ path);
|
||||
path = path.replace("WEB-INF/classes/", "");
|
||||
path = path.replace("file:/", "");
|
||||
bufferImg = ImageIO.read(new File(path));
|
||||
ImageIO.write(bufferImg, imagePath.substring(imagePath.indexOf(".") + 1, imagePath.length()), byteArrayOut);
|
||||
byte[] value = byteArrayOut.toByteArray();
|
||||
patriarch.createPicture(anchor, row.getSheet().getWorkbook().addPicture(value, getImageType(value)));
|
||||
} catch (IOException e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
} else {
|
||||
byte[] value = (byte[]) (entity.getMethods() != null ? getFieldBySomeMethod(entity.getMethods(), obj) : entity.getMethod().invoke(obj, new Object[] {}));
|
||||
if (value != null) {
|
||||
patriarch.createPicture(anchor, row.getSheet().getWorkbook().addPicture(value, getImageType(value)));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private int createIndexCell(Row row, int index, ExcelExportEntity excelExportEntity) {
|
||||
if (excelExportEntity.getName().equals("序号") && excelExportEntity.getFormat().equals(PoiBaseConstants.IS_ADD_INDEX)) {
|
||||
createStringCell(row, 0, currentIndex + "", index % 2 == 0 ? getStyles(false, null) : getStyles(true, null), null);
|
||||
currentIndex = currentIndex + 1;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建List之后的各个Cells
|
||||
*
|
||||
* @param patriarch
|
||||
* @param index
|
||||
* @param cellNum
|
||||
* @param obj
|
||||
* @param excelParams
|
||||
* @param sheet
|
||||
* @param workbook
|
||||
* @throws Exception
|
||||
*/
|
||||
public void createListCells(Drawing patriarch, int index, int cellNum, Object obj, List<ExcelExportEntity> excelParams, Sheet sheet, Workbook workbook) throws Exception {
|
||||
ExcelExportEntity entity;
|
||||
Row row;
|
||||
if (sheet.getRow(index) == null) {
|
||||
row = sheet.createRow(index);
|
||||
row.setHeight(getRowHeight(excelParams));
|
||||
} else {
|
||||
row = sheet.getRow(index);
|
||||
}
|
||||
for (int k = 0, paramSize = excelParams.size(); k < paramSize; k++) {
|
||||
entity = excelParams.get(k);
|
||||
Object value = getCellValue(entity, obj);
|
||||
if (entity.getType() == 1) {
|
||||
createStringCell(row, cellNum++, value == null ? "" : value.toString(), row.getRowNum() % 2 == 0 ? getStyles(false, entity) : getStyles(true, entity), entity);
|
||||
} else if (entity.getType() == 4){
|
||||
createNumericCell(row, cellNum++, value == null ? "" : value.toString(), index % 2 == 0 ? getStyles(false, entity) : getStyles(true, entity), entity);
|
||||
} else{
|
||||
createImageCell(patriarch, entity, row, cellNum++, value == null ? "" : value.toString(), obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void createNumericCell (Row row, int index, String text, CellStyle style, ExcelExportEntity entity) {
|
||||
Cell cell = row.createCell(index);
|
||||
if(StringUtils.isEmpty(text)){
|
||||
cell.setCellValue("");
|
||||
cell.setCellType(Cell.CELL_TYPE_BLANK);
|
||||
}else{
|
||||
cell.setCellValue(Double.parseDouble(text));
|
||||
cell.setCellType(Cell.CELL_TYPE_NUMERIC);
|
||||
}
|
||||
if (style != null) {
|
||||
cell.setCellStyle(style);
|
||||
}
|
||||
addStatisticsData(index, text, entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建文本类型的Cell
|
||||
*
|
||||
* @param row
|
||||
* @param index
|
||||
* @param text
|
||||
* @param style
|
||||
* @param entity
|
||||
*/
|
||||
public void createStringCell(Row row, int index, String text, CellStyle style, ExcelExportEntity entity) {
|
||||
Cell cell = row.createCell(index);
|
||||
if (style != null && style.getDataFormat() > 0 && style.getDataFormat() < 12) {
|
||||
cell.setCellValue(Double.parseDouble(text));
|
||||
cell.setCellType(Cell.CELL_TYPE_NUMERIC);
|
||||
}else{
|
||||
RichTextString Rtext;
|
||||
if (type.equals(ExcelType.HSSF)) {
|
||||
Rtext = new HSSFRichTextString(text);
|
||||
} else {
|
||||
Rtext = new XSSFRichTextString(text);
|
||||
}
|
||||
cell.setCellValue(Rtext);
|
||||
}
|
||||
if (style != null) {
|
||||
cell.setCellStyle(style);
|
||||
}
|
||||
addStatisticsData(index, text, entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建统计行
|
||||
*
|
||||
* @param styles
|
||||
* @param sheet
|
||||
*/
|
||||
public void addStatisticsRow(CellStyle styles, Sheet sheet) {
|
||||
if (statistics.size() > 0) {
|
||||
Row row = sheet.createRow(sheet.getLastRowNum() + 1);
|
||||
Set<Integer> keys = statistics.keySet();
|
||||
createStringCell(row, 0, "合计", styles, null);
|
||||
for (Integer key : keys) {
|
||||
createStringCell(row, key, DOUBLE_FORMAT.format(statistics.get(key)), styles, null);
|
||||
}
|
||||
statistics.clear();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 合计统计信息
|
||||
*
|
||||
* @param index
|
||||
* @param text
|
||||
* @param entity
|
||||
*/
|
||||
private void addStatisticsData(Integer index, String text, ExcelExportEntity entity) {
|
||||
if (entity != null && entity.isStatistics()) {
|
||||
Double temp = 0D;
|
||||
if (!statistics.containsKey(index)) {
|
||||
statistics.put(index, temp);
|
||||
}
|
||||
try {
|
||||
temp = Double.valueOf(text);
|
||||
} catch (NumberFormatException e) {
|
||||
}
|
||||
statistics.put(index, statistics.get(index) + temp);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取导出报表的字段总长度
|
||||
*
|
||||
* @param excelParams
|
||||
* @return
|
||||
*/
|
||||
public int getFieldWidth(List<ExcelExportEntity> excelParams) {
|
||||
int length = -1;// 从0开始计算单元格的
|
||||
for (ExcelExportEntity entity : excelParams) {
|
||||
length += entity.getList() != null ? entity.getList().size() : 1;
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取图片类型,设置图片插入类型
|
||||
*
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
public int getImageType(byte[] value) {
|
||||
String type = PoiPublicUtil.getFileExtendName(value);
|
||||
if (type.equalsIgnoreCase("JPG")) {
|
||||
return Workbook.PICTURE_TYPE_JPEG;
|
||||
} else if (type.equalsIgnoreCase("PNG")) {
|
||||
return Workbook.PICTURE_TYPE_PNG;
|
||||
}
|
||||
return Workbook.PICTURE_TYPE_JPEG;
|
||||
}
|
||||
|
||||
private Map<Integer, int[]> getMergeDataMap(List<ExcelExportEntity> excelParams) {
|
||||
Map<Integer, int[]> mergeMap = new HashMap<Integer, int[]>();
|
||||
// 设置参数顺序,为之后合并单元格做准备
|
||||
int i = 0;
|
||||
for (ExcelExportEntity entity : excelParams) {
|
||||
if (entity.isMergeVertical()) {
|
||||
mergeMap.put(i, entity.getMergeRely());
|
||||
}
|
||||
if (entity.getList() != null) {
|
||||
for (ExcelExportEntity inner : entity.getList()) {
|
||||
if (inner.isMergeVertical()) {
|
||||
mergeMap.put(i, inner.getMergeRely());
|
||||
}
|
||||
i++;
|
||||
}
|
||||
} else {
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return mergeMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取样式
|
||||
*
|
||||
* @param entity
|
||||
* @param needOne
|
||||
* @return
|
||||
*/
|
||||
public CellStyle getStyles(boolean needOne, ExcelExportEntity entity) {
|
||||
return excelExportStyler.getStyles(needOne, entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* 合并单元格
|
||||
*
|
||||
* @param sheet
|
||||
* @param excelParams
|
||||
* @param titleHeight
|
||||
*/
|
||||
public void mergeCells(Sheet sheet, List<ExcelExportEntity> excelParams, int titleHeight) {
|
||||
Map<Integer, int[]> mergeMap = getMergeDataMap(excelParams);
|
||||
PoiMergeCellUtil.mergeCells(sheet, mergeMap, titleHeight);
|
||||
}
|
||||
|
||||
public void setCellWith(List<ExcelExportEntity> excelParams, Sheet sheet) {
|
||||
int index = 0;
|
||||
for (int i = 0; i < excelParams.size(); i++) {
|
||||
if (excelParams.get(i).getList() != null) {
|
||||
List<ExcelExportEntity> list = excelParams.get(i).getList();
|
||||
for (int j = 0; j < list.size(); j++) {
|
||||
sheet.setColumnWidth(index, (int) (256 * list.get(j).getWidth()));
|
||||
index++;
|
||||
}
|
||||
} else {
|
||||
sheet.setColumnWidth(index, (int) (256 * excelParams.get(i).getWidth()));
|
||||
index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setCurrentIndex(int currentIndex) {
|
||||
this.currentIndex = currentIndex;
|
||||
}
|
||||
|
||||
public void setExcelExportStyler(IExcelExportStyler excelExportStyler) {
|
||||
this.excelExportStyler = excelExportStyler;
|
||||
}
|
||||
|
||||
public IExcelExportStyler getExcelExportStyler() {
|
||||
return excelExportStyler;
|
||||
}
|
||||
|
||||
}
|
||||
+366
@@ -0,0 +1,366 @@
|
||||
package com.pig4cloud.pigx.common.poi.excel.export.base;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.pig4cloud.pigx.common.core.util.ApplicationContextUtil;
|
||||
import com.pig4cloud.pigx.common.dict.service.AutoPoiDictServiceI;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import com.pig4cloud.pigx.common.poi.excel.annotation.Excel;
|
||||
import com.pig4cloud.pigx.common.poi.excel.annotation.ExcelCollection;
|
||||
import com.pig4cloud.pigx.common.poi.excel.annotation.ExcelEntity;
|
||||
import com.pig4cloud.pigx.common.poi.excel.entity.params.ExcelExportEntity;
|
||||
import com.pig4cloud.pigx.common.poi.handler.inter.IExcelDataHandler;
|
||||
import com.pig4cloud.pigx.common.poi.util.PoiPublicUtil;
|
||||
|
||||
/**
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
* 导出基础处理,不设计POI,只设计对象,保证复用性
|
||||
*/
|
||||
public class ExportBase {
|
||||
|
||||
protected IExcelDataHandler dataHanlder;
|
||||
|
||||
protected List<String> needHanlderList;
|
||||
|
||||
/**
|
||||
* 创建导出实体对象
|
||||
*
|
||||
* @param field
|
||||
* @param targetId
|
||||
* @param pojoClass
|
||||
* @param getMethods
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
private ExcelExportEntity createExcelExportEntity(Field field, String targetId, Class<?> pojoClass, List<Method> getMethods) throws Exception {
|
||||
Excel excel = field.getAnnotation(Excel.class);
|
||||
ExcelExportEntity excelEntity = new ExcelExportEntity();
|
||||
excelEntity.setType(excel.type());
|
||||
getExcelField(targetId, field, excelEntity, excel, pojoClass);
|
||||
if (getMethods != null) {
|
||||
List<Method> newMethods = new ArrayList<Method>();
|
||||
newMethods.addAll(getMethods);
|
||||
newMethods.add(excelEntity.getMethod());
|
||||
excelEntity.setMethods(newMethods);
|
||||
}
|
||||
return excelEntity;
|
||||
}
|
||||
|
||||
private Object formatValue(Object value, ExcelExportEntity entity) throws Exception {
|
||||
Date temp = null;
|
||||
if (value instanceof String) {
|
||||
SimpleDateFormat format = new SimpleDateFormat(entity.getDatabaseFormat());
|
||||
temp = format.parse(value.toString());
|
||||
} else if (value instanceof Date) {
|
||||
temp = (Date) value;
|
||||
}
|
||||
if (temp != null) {
|
||||
SimpleDateFormat format = new SimpleDateFormat(entity.getFormat());
|
||||
value = format.format(temp);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取需要导出的全部字段
|
||||
*
|
||||
* @param exclusions
|
||||
* @param targetId
|
||||
* 目标ID
|
||||
* @param fields
|
||||
* @throws Exception
|
||||
*/
|
||||
public void getAllExcelField(String[] exclusions, String targetId, Field[] fields, List<ExcelExportEntity> excelParams, Class<?> pojoClass, List<Method> getMethods) throws Exception {
|
||||
List<String> exclusionsList = exclusions != null ? Arrays.asList(exclusions) : null;
|
||||
ExcelExportEntity excelEntity;
|
||||
// 遍历整个filed
|
||||
for (int i = 0; i < fields.length; i++) {
|
||||
Field field = fields[i];
|
||||
// 先判断是不是collection,在判断是不是java自带对象,之后就是我们自己的对象了
|
||||
if (PoiPublicUtil.isNotUserExcelUserThis(exclusionsList, field, targetId)) {
|
||||
continue;
|
||||
}
|
||||
// 首先判断Excel 可能一下特殊数据用户回自定义处理
|
||||
if (field.getAnnotation(Excel.class) != null) {
|
||||
excelParams.add(createExcelExportEntity(field, targetId, pojoClass, getMethods));
|
||||
} else if (PoiPublicUtil.isCollection(field.getType())) {
|
||||
ExcelCollection excel = field.getAnnotation(ExcelCollection.class);
|
||||
ParameterizedType pt = (ParameterizedType) field.getGenericType();
|
||||
Class<?> clz = (Class<?>) pt.getActualTypeArguments()[0];
|
||||
List<ExcelExportEntity> list = new ArrayList<ExcelExportEntity>();
|
||||
getAllExcelField(exclusions, StringUtils.isNotEmpty(excel.id()) ? excel.id() : targetId, PoiPublicUtil.getClassFields(clz), list, clz, null);
|
||||
excelEntity = new ExcelExportEntity();
|
||||
excelEntity.setName(getExcelName(excel.name(), targetId));
|
||||
excelEntity.setOrderNum(getCellOrder(excel.orderNum(), targetId));
|
||||
excelEntity.setMethod(PoiPublicUtil.getMethod(field.getName(), pojoClass));
|
||||
excelEntity.setList(list);
|
||||
excelParams.add(excelEntity);
|
||||
} else {
|
||||
List<Method> newMethods = new ArrayList<Method>();
|
||||
if (getMethods != null) {
|
||||
newMethods.addAll(getMethods);
|
||||
}
|
||||
newMethods.add(PoiPublicUtil.getMethod(field.getName(), pojoClass));
|
||||
ExcelEntity excel = field.getAnnotation(ExcelEntity.class);
|
||||
getAllExcelField(exclusions, StringUtils.isNotEmpty(excel.id()) ? excel.id() : targetId, PoiPublicUtil.getClassFields(field.getType()), excelParams, field.getType(), newMethods);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取这个字段的顺序
|
||||
*
|
||||
* @param orderNum
|
||||
* @param targetId
|
||||
* @return
|
||||
*/
|
||||
public int getCellOrder(String orderNum, String targetId) {
|
||||
if (isInteger(orderNum) || targetId == null) {
|
||||
return Integer.valueOf(orderNum);
|
||||
}
|
||||
String[] arr = orderNum.split(",");
|
||||
String[] temp;
|
||||
for (String str : arr) {
|
||||
temp = str.split("_");
|
||||
if (targetId.equals(temp[1])) {
|
||||
return Integer.valueOf(temp[0]);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取填如这个cell的值,提供一些附加功能
|
||||
*
|
||||
* @param entity
|
||||
* @param obj
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public Object getCellValue(ExcelExportEntity entity, Object obj) throws Exception {
|
||||
Object value;
|
||||
if (obj instanceof Map) {
|
||||
value = ((Map<?, ?>) obj).get(entity.getKey());
|
||||
} else {
|
||||
value = entity.getMethods() != null ? getFieldBySomeMethod(entity.getMethods(), obj) : entity.getMethod().invoke(obj, new Object[] {});
|
||||
}
|
||||
if (StringUtils.isNotEmpty(entity.getFormat())) {
|
||||
value = formatValue(value, entity);
|
||||
}
|
||||
if (entity.getReplace() != null && entity.getReplace().length > 0) {
|
||||
if(value == null){
|
||||
//String.valueOf(value) 如果value为null 则返回"null"
|
||||
value = "";
|
||||
}
|
||||
if(entity.isMultiReplace()){
|
||||
value = multiReplaceValue(entity.getReplace(), String.valueOf(value));
|
||||
}else{
|
||||
value = replaceValue(entity.getReplace(), String.valueOf(value));
|
||||
}
|
||||
}
|
||||
if (needHanlderList != null && needHanlderList.contains(entity.getName())) {
|
||||
value = dataHanlder.exportHandler(obj, entity.getName(), value);
|
||||
}
|
||||
if (StringUtils.isNotEmpty(entity.getSuffix()) && value != null) {
|
||||
value = value + entity.getSuffix();
|
||||
}
|
||||
return value == null ? "" : value.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取集合的值
|
||||
*
|
||||
* @param entity
|
||||
* @param obj
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public Collection<?> getListCellValue(ExcelExportEntity entity, Object obj) throws Exception {
|
||||
Object value;
|
||||
if (obj instanceof Map) {
|
||||
value = ((Map<?, ?>) obj).get(entity.getKey());
|
||||
} else {
|
||||
value = (Collection<?>) entity.getMethod().invoke(obj, new Object[] {});
|
||||
}
|
||||
return (Collection<?>) value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 注解到导出对象的转换
|
||||
*
|
||||
* @param targetId
|
||||
* @param field
|
||||
* @param excelEntity
|
||||
* @param excel
|
||||
* @param pojoClass
|
||||
* @throws Exception
|
||||
*/
|
||||
private void getExcelField(String targetId, Field field, ExcelExportEntity excelEntity, Excel excel, Class<?> pojoClass) throws Exception {
|
||||
excelEntity.setName(getExcelName(excel.name(), targetId));
|
||||
excelEntity.setWidth(excel.width());
|
||||
excelEntity.setHeight(excel.height());
|
||||
excelEntity.setNeedMerge(excel.needMerge());
|
||||
excelEntity.setMergeVertical(excel.mergeVertical());
|
||||
excelEntity.setMergeRely(excel.mergeRely());
|
||||
excelEntity.setReplace(excel.replace());
|
||||
if(StringUtils.isNotEmpty(excel.dicCode())){
|
||||
AutoPoiDictServiceI bossDictService = null;
|
||||
try {
|
||||
bossDictService = ApplicationContextUtil.getContext().getBean(AutoPoiDictServiceI.class);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
if(bossDictService!=null){
|
||||
String[] dictReplace = bossDictService.queryDict(excel.dictTable(), excel.dicCode(), excel.dicText());
|
||||
if(excelEntity.getReplace()!=null && dictReplace!=null && dictReplace.length!=0){
|
||||
excelEntity.setReplace(dictReplace);
|
||||
}
|
||||
}
|
||||
}
|
||||
excelEntity.setOrderNum(getCellOrder(excel.orderNum(), targetId));
|
||||
excelEntity.setWrap(excel.isWrap());
|
||||
excelEntity.setExportImageType(excel.imageType());
|
||||
excelEntity.setSuffix(excel.suffix());
|
||||
excelEntity.setDatabaseFormat(excel.databaseFormat());
|
||||
excelEntity.setFormat(StringUtils.isNotEmpty(excel.exportFormat()) ? excel.exportFormat() : excel.format());
|
||||
excelEntity.setStatistics(excel.isStatistics());
|
||||
String fieldname = field.getName();
|
||||
excelEntity.setMethod(PoiPublicUtil.getMethod(fieldname, pojoClass,excel.exportConvert()));
|
||||
excelEntity.setMultiReplace(excel.multiReplace());
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断在这个单元格显示的名称
|
||||
*
|
||||
* @param exportName
|
||||
* @param targetId
|
||||
* @return
|
||||
*/
|
||||
public String getExcelName(String exportName, String targetId) {
|
||||
if (exportName.indexOf(",") < 0 || targetId==null) {
|
||||
return exportName;
|
||||
}
|
||||
String[] arr = exportName.split(",");
|
||||
for (String str : arr) {
|
||||
if (str.indexOf(targetId) != -1) {
|
||||
return str.split("_")[0];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 多个反射获取值
|
||||
*
|
||||
* @param list
|
||||
* @param t
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public Object getFieldBySomeMethod(List<Method> list, Object t) throws Exception {
|
||||
for (Method m : list) {
|
||||
if (t == null) {
|
||||
t = "";
|
||||
break;
|
||||
}
|
||||
t = m.invoke(t, new Object[] {});
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据注解获取行高
|
||||
*
|
||||
* @param excelParams
|
||||
* @return
|
||||
*/
|
||||
public short getRowHeight(List<ExcelExportEntity> excelParams) {
|
||||
double maxHeight = 0;
|
||||
for (int i = 0; i < excelParams.size(); i++) {
|
||||
maxHeight = maxHeight > excelParams.get(i).getHeight() ? maxHeight : excelParams.get(i).getHeight();
|
||||
if (excelParams.get(i).getList() != null) {
|
||||
for (int j = 0; j < excelParams.get(i).getList().size(); j++) {
|
||||
maxHeight = maxHeight > excelParams.get(i).getList().get(j).getHeight() ? maxHeight : excelParams.get(i).getList().get(j).getHeight();
|
||||
}
|
||||
}
|
||||
}
|
||||
return (short) (maxHeight * 50);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断字符串是否是整数
|
||||
*/
|
||||
public boolean isInteger(String value) {
|
||||
try {
|
||||
Integer.parseInt(value);
|
||||
return true;
|
||||
} catch (NumberFormatException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private Object replaceValue(String[] replace, String value) {
|
||||
String[] temp;
|
||||
for (String str : replace) {
|
||||
temp = str.split("_");
|
||||
if (value.equals(temp[1])) {
|
||||
value = temp[0];
|
||||
break;
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 如果需要被替换的值是多选项,则每一项之间有逗号隔开,走以下方法
|
||||
*/
|
||||
private Object multiReplaceValue(String[] replace, String value) {
|
||||
if(value.indexOf(",")>0){
|
||||
String[] radioVals = value.split(",");
|
||||
String[] temp;
|
||||
String result = "";
|
||||
for(int i =0;i<radioVals.length;i++){
|
||||
String radio = radioVals[i];
|
||||
for (String str : replace) {
|
||||
temp = str.split("_");
|
||||
if (radio.equals(temp[1])) {
|
||||
result = result.concat(temp[0])+",";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(result.equals("")){
|
||||
result = value;
|
||||
}else{
|
||||
result = result.substring(0, result.length()-1);
|
||||
}
|
||||
return result;
|
||||
}else{
|
||||
return replaceValue(replace, value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 对字段根据用户设置排序
|
||||
*/
|
||||
public void sortAllParams(List<ExcelExportEntity> excelParams) {
|
||||
Collections.sort(excelParams);
|
||||
for (ExcelExportEntity entity : excelParams) {
|
||||
if (entity.getList() != null) {
|
||||
Collections.sort(entity.getList());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
package com.pig4cloud.pigx.common.poi.excel.export.styler;
|
||||
|
||||
import org.apache.poi.ss.usermodel.BuiltinFormats;
|
||||
import org.apache.poi.ss.usermodel.CellStyle;
|
||||
import org.apache.poi.ss.usermodel.Workbook;
|
||||
import com.pig4cloud.pigx.common.poi.excel.entity.params.ExcelExportEntity;
|
||||
|
||||
/**
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
* 抽象接口提供两个公共方法
|
||||
*/
|
||||
public abstract class AbstractExcelExportStyler implements IExcelExportStyler {
|
||||
// 单行
|
||||
protected CellStyle stringNoneStyle;
|
||||
protected CellStyle stringNoneWrapStyle;
|
||||
// 间隔行
|
||||
protected CellStyle stringSeptailStyle;
|
||||
protected CellStyle stringSeptailWrapStyle;
|
||||
|
||||
protected Workbook workbook;
|
||||
|
||||
protected static final short STRING_FORMAT = (short) BuiltinFormats.getBuiltinFormat("TEXT");
|
||||
|
||||
protected void createStyles(Workbook workbook) {
|
||||
this.stringNoneStyle = stringNoneStyle(workbook, false);
|
||||
this.stringNoneWrapStyle = stringNoneStyle(workbook, true);
|
||||
this.stringSeptailStyle = stringSeptailStyle(workbook, false);
|
||||
this.stringSeptailWrapStyle = stringSeptailStyle(workbook, true);
|
||||
this.workbook = workbook;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CellStyle getStyles(boolean noneStyler, ExcelExportEntity entity) {
|
||||
if (noneStyler && (entity == null || entity.isWrap())) {
|
||||
return stringNoneWrapStyle;
|
||||
}
|
||||
if (noneStyler) {
|
||||
return stringNoneStyle;
|
||||
}
|
||||
if (noneStyler == false && (entity == null || entity.isWrap())) {
|
||||
return stringSeptailWrapStyle;
|
||||
}
|
||||
return stringSeptailStyle;
|
||||
}
|
||||
|
||||
public CellStyle stringNoneStyle(Workbook workbook, boolean isWarp) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public CellStyle stringSeptailStyle(Workbook workbook, boolean isWarp) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
package com.pig4cloud.pigx.common.poi.excel.export.styler;
|
||||
|
||||
import org.apache.poi.ss.usermodel.CellStyle;
|
||||
import org.apache.poi.ss.usermodel.Font;
|
||||
import org.apache.poi.ss.usermodel.Workbook;
|
||||
|
||||
/**
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
* 带有边框的Excel样式
|
||||
*/
|
||||
public class ExcelExportStylerBorderImpl extends AbstractExcelExportStyler implements IExcelExportStyler {
|
||||
|
||||
public ExcelExportStylerBorderImpl(Workbook workbook) {
|
||||
super.createStyles(workbook);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CellStyle getHeaderStyle(short color) {
|
||||
CellStyle titleStyle = workbook.createCellStyle();
|
||||
Font font = workbook.createFont();
|
||||
font.setFontHeightInPoints((short) 12);
|
||||
titleStyle.setFont(font);
|
||||
titleStyle.setBorderLeft((short) 1); // 左边框
|
||||
titleStyle.setBorderRight((short) 1); // 右边框
|
||||
titleStyle.setBorderBottom((short) 1);
|
||||
titleStyle.setBorderTop((short) 1);
|
||||
titleStyle.setAlignment(CellStyle.ALIGN_CENTER);
|
||||
titleStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
|
||||
return titleStyle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CellStyle stringNoneStyle(Workbook workbook, boolean isWarp) {
|
||||
CellStyle style = workbook.createCellStyle();
|
||||
style.setBorderLeft((short) 1); // 左边框
|
||||
style.setBorderRight((short) 1); // 右边框
|
||||
style.setBorderBottom((short) 1);
|
||||
style.setBorderTop((short) 1);
|
||||
style.setAlignment(CellStyle.ALIGN_CENTER);
|
||||
style.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
|
||||
style.setDataFormat(STRING_FORMAT);
|
||||
if (isWarp) {
|
||||
style.setWrapText(true);
|
||||
}
|
||||
return style;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CellStyle getTitleStyle(short color) {
|
||||
CellStyle titleStyle = workbook.createCellStyle();
|
||||
titleStyle.setBorderLeft((short) 1); // 左边框
|
||||
titleStyle.setBorderRight((short) 1); // 右边框
|
||||
titleStyle.setBorderBottom((short) 1);
|
||||
titleStyle.setBorderTop((short) 1);
|
||||
titleStyle.setAlignment(CellStyle.ALIGN_CENTER);
|
||||
titleStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
|
||||
titleStyle.setWrapText(true);
|
||||
return titleStyle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CellStyle stringSeptailStyle(Workbook workbook, boolean isWarp) {
|
||||
return isWarp ? stringNoneWrapStyle : stringNoneStyle;
|
||||
}
|
||||
|
||||
}
|
||||
+76
@@ -0,0 +1,76 @@
|
||||
package com.pig4cloud.pigx.common.poi.excel.export.styler;
|
||||
|
||||
import org.apache.poi.ss.usermodel.CellStyle;
|
||||
import org.apache.poi.ss.usermodel.Font;
|
||||
import org.apache.poi.ss.usermodel.Workbook;
|
||||
|
||||
/**
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
* 带有样式的导出服务
|
||||
*/
|
||||
public class ExcelExportStylerColorImpl extends AbstractExcelExportStyler implements IExcelExportStyler {
|
||||
|
||||
public ExcelExportStylerColorImpl(Workbook workbook) {
|
||||
super.createStyles(workbook);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CellStyle getHeaderStyle(short headerColor) {
|
||||
CellStyle titleStyle = workbook.createCellStyle();
|
||||
Font font = workbook.createFont();
|
||||
font.setFontHeightInPoints((short) 24);
|
||||
titleStyle.setFont(font);
|
||||
titleStyle.setFillForegroundColor(headerColor);
|
||||
titleStyle.setAlignment(CellStyle.ALIGN_CENTER);
|
||||
titleStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
|
||||
return titleStyle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CellStyle stringNoneStyle(Workbook workbook, boolean isWarp) {
|
||||
CellStyle style = workbook.createCellStyle();
|
||||
style.setBorderLeft((short) 1); // 左边框
|
||||
style.setBorderRight((short) 1); // 右边框
|
||||
style.setBorderBottom((short) 1);
|
||||
style.setBorderTop((short) 1);
|
||||
style.setAlignment(CellStyle.ALIGN_CENTER);
|
||||
style.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
|
||||
style.setDataFormat(STRING_FORMAT);
|
||||
if (isWarp) {
|
||||
style.setWrapText(true);
|
||||
}
|
||||
return style;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CellStyle getTitleStyle(short color) {
|
||||
CellStyle titleStyle = workbook.createCellStyle();
|
||||
titleStyle.setFillForegroundColor(color); // 填充的背景颜色
|
||||
titleStyle.setAlignment(CellStyle.ALIGN_CENTER);
|
||||
titleStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
|
||||
titleStyle.setFillPattern(CellStyle.SOLID_FOREGROUND); // 填充图案
|
||||
titleStyle.setWrapText(true);
|
||||
return titleStyle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CellStyle stringSeptailStyle(Workbook workbook, boolean isWarp) {
|
||||
CellStyle style = workbook.createCellStyle();
|
||||
style.setBorderLeft((short) 1); // 左边框
|
||||
style.setBorderRight((short) 1); // 右边框
|
||||
style.setBorderBottom((short) 1);
|
||||
style.setBorderTop((short) 1);
|
||||
style.setFillForegroundColor((short) 41); // 填充的背景颜色
|
||||
style.setFillPattern(CellStyle.SOLID_FOREGROUND); // 填充图案
|
||||
style.setAlignment(CellStyle.ALIGN_CENTER);
|
||||
style.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
|
||||
style.setDataFormat(STRING_FORMAT);
|
||||
if (isWarp) {
|
||||
style.setWrapText(true);
|
||||
}
|
||||
return style;
|
||||
}
|
||||
|
||||
}
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
package com.pig4cloud.pigx.common.poi.excel.export.styler;
|
||||
|
||||
import org.apache.poi.ss.usermodel.CellStyle;
|
||||
import org.apache.poi.ss.usermodel.Font;
|
||||
import org.apache.poi.ss.usermodel.Workbook;
|
||||
|
||||
/**
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
* 样式的默认实现
|
||||
*/
|
||||
public class ExcelExportStylerDefaultImpl extends AbstractExcelExportStyler implements IExcelExportStyler {
|
||||
|
||||
public ExcelExportStylerDefaultImpl(Workbook workbook) {
|
||||
super.createStyles(workbook);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CellStyle getTitleStyle(short color) {
|
||||
CellStyle titleStyle = workbook.createCellStyle();
|
||||
titleStyle.setAlignment(CellStyle.ALIGN_CENTER);
|
||||
titleStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
|
||||
titleStyle.setWrapText(true);
|
||||
return titleStyle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CellStyle stringSeptailStyle(Workbook workbook, boolean isWarp) {
|
||||
CellStyle style = workbook.createCellStyle();
|
||||
style.setAlignment(CellStyle.ALIGN_CENTER);
|
||||
style.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
|
||||
style.setDataFormat(STRING_FORMAT);
|
||||
if (isWarp) {
|
||||
style.setWrapText(true);
|
||||
}
|
||||
return style;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CellStyle getHeaderStyle(short color) {
|
||||
CellStyle titleStyle = workbook.createCellStyle();
|
||||
Font font = workbook.createFont();
|
||||
font.setFontHeightInPoints((short) 12);
|
||||
titleStyle.setFont(font);
|
||||
titleStyle.setAlignment(CellStyle.ALIGN_CENTER);
|
||||
titleStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
|
||||
return titleStyle;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CellStyle stringNoneStyle(Workbook workbook, boolean isWarp) {
|
||||
CellStyle style = workbook.createCellStyle();
|
||||
style.setAlignment(CellStyle.ALIGN_CENTER);
|
||||
style.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
|
||||
style.setDataFormat(STRING_FORMAT);
|
||||
if (isWarp) {
|
||||
style.setWrapText(true);
|
||||
}
|
||||
return style;
|
||||
}
|
||||
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
package com.pig4cloud.pigx.common.poi.excel.export.styler;
|
||||
|
||||
import org.apache.poi.ss.usermodel.CellStyle;
|
||||
import com.pig4cloud.pigx.common.poi.excel.entity.params.ExcelExportEntity;
|
||||
|
||||
/**
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
* Excel导出样式接口
|
||||
*/
|
||||
public interface IExcelExportStyler {
|
||||
|
||||
/**
|
||||
* 列表头样式
|
||||
*
|
||||
* @param headerColor
|
||||
* @return
|
||||
*/
|
||||
public CellStyle getHeaderStyle(short headerColor);
|
||||
|
||||
/**
|
||||
* 标题样式
|
||||
*
|
||||
* @param color
|
||||
* @return
|
||||
*/
|
||||
public CellStyle getTitleStyle(short color);
|
||||
|
||||
/**
|
||||
* 获取样式方法
|
||||
*
|
||||
* @param noneStyler
|
||||
* @param entity
|
||||
* @return
|
||||
*/
|
||||
public CellStyle getStyles(boolean noneStyler, ExcelExportEntity entity);
|
||||
|
||||
}
|
||||
+444
@@ -0,0 +1,444 @@
|
||||
package com.pig4cloud.pigx.common.poi.excel.export.template;
|
||||
|
||||
import com.pig4cloud.pigx.common.poi.cache.ExcelCache;
|
||||
import com.pig4cloud.pigx.common.poi.excel.annotation.ExcelTarget;
|
||||
import com.pig4cloud.pigx.common.poi.excel.entity.TemplateExportParams;
|
||||
import com.pig4cloud.pigx.common.poi.excel.entity.enmus.ExcelType;
|
||||
import com.pig4cloud.pigx.common.poi.excel.entity.params.ExcelExportEntity;
|
||||
import com.pig4cloud.pigx.common.poi.excel.entity.params.ExcelTemplateParams;
|
||||
import com.pig4cloud.pigx.common.poi.excel.export.base.ExcelExportBase;
|
||||
import com.pig4cloud.pigx.common.poi.excel.export.styler.IExcelExportStyler;
|
||||
import com.pig4cloud.pigx.common.poi.exception.excel.ExcelExportException;
|
||||
import com.pig4cloud.pigx.common.poi.exception.excel.enums.ExcelExportEnum;
|
||||
import com.pig4cloud.pigx.common.poi.util.PoiPublicUtil;
|
||||
import com.pig4cloud.pigx.common.poi.util.PoiSheetUtility;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.poi.ss.usermodel.*;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.*;
|
||||
|
||||
import static com.pig4cloud.pigx.common.poi.util.PoiElUtil.*;
|
||||
|
||||
/**
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
* Excel 导出根据模板导出
|
||||
*/
|
||||
@Slf4j
|
||||
public final class ExcelExportOfTemplateUtil extends ExcelExportBase {
|
||||
|
||||
/**
|
||||
* 缓存TEMP 的for each创建的cell ,跳过这个cell的模板语法查找,提高效率
|
||||
*/
|
||||
private Set<String> tempCreateCellSet = new HashSet<String>();
|
||||
/**
|
||||
* 模板参数,全局都用到
|
||||
*/
|
||||
private TemplateExportParams teplateParams;
|
||||
|
||||
/**
|
||||
* 往Sheet 填充正常数据,根据表头信息 使用导入的部分逻辑,坐对象映射
|
||||
* @param pojoClass
|
||||
* @param dataSet
|
||||
* @param sheet
|
||||
* @param workbook
|
||||
* @throws Exception
|
||||
*/
|
||||
private void addDataToSheet(Class<?> pojoClass, Collection<?> dataSet, Sheet sheet, Workbook workbook) throws Exception {
|
||||
|
||||
if (workbook instanceof XSSFWorkbook) {
|
||||
super.type = ExcelType.XSSF;
|
||||
}
|
||||
// 获取表头数据
|
||||
Map<String, Integer> titlemap = getTitleMap(sheet);
|
||||
Drawing patriarch = sheet.createDrawingPatriarch();
|
||||
// 得到所有字段
|
||||
Field[] fileds = PoiPublicUtil.getClassFields(pojoClass);
|
||||
ExcelTarget etarget = pojoClass.getAnnotation(ExcelTarget.class);
|
||||
String targetId = null;
|
||||
if (etarget != null) {
|
||||
targetId = etarget.value();
|
||||
}
|
||||
// 获取实体对象的导出数据
|
||||
List<ExcelExportEntity> excelParams = new ArrayList<ExcelExportEntity>();
|
||||
getAllExcelField(null, targetId, fileds, excelParams, pojoClass, null);
|
||||
// 根据表头进行筛选排序
|
||||
sortAndFilterExportField(excelParams, titlemap);
|
||||
short rowHeight = getRowHeight(excelParams);
|
||||
int index = teplateParams.getHeadingRows() + teplateParams.getHeadingStartRow(), titleHeight = index;
|
||||
// 下移数据,模拟插入
|
||||
sheet.shiftRows(teplateParams.getHeadingRows() + teplateParams.getHeadingStartRow(), sheet.getLastRowNum(), getShiftRows(dataSet, excelParams), true, true);
|
||||
if (excelParams.size() == 0) {
|
||||
return;
|
||||
}
|
||||
Iterator<?> its = dataSet.iterator();
|
||||
while (its.hasNext()) {
|
||||
Object t = its.next();
|
||||
index += createCells(patriarch, index, t, excelParams, sheet, workbook, rowHeight);
|
||||
}
|
||||
// 合并同类项
|
||||
mergeCells(sheet, excelParams, titleHeight);
|
||||
}
|
||||
|
||||
/**
|
||||
* 下移数据
|
||||
*
|
||||
* @param dataSet
|
||||
* @param excelParams
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
private int getShiftRows(Collection<?> dataSet, List<ExcelExportEntity> excelParams) throws Exception {
|
||||
int size = 0;
|
||||
Iterator<?> its = dataSet.iterator();
|
||||
while (its.hasNext()) {
|
||||
Object t = its.next();
|
||||
size += getOneObjectSize(t, excelParams);
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取单个对象的高度,主要是处理一堆多的情况
|
||||
*
|
||||
* @param t
|
||||
* @param excelParams
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public int getOneObjectSize(Object t, List<ExcelExportEntity> excelParams) throws Exception {
|
||||
ExcelExportEntity entity;
|
||||
int maxHeight = 1;
|
||||
for (int k = 0, paramSize = excelParams.size(); k < paramSize; k++) {
|
||||
entity = excelParams.get(k);
|
||||
if (entity.getList() != null) {
|
||||
Collection<?> list = (Collection<?>) entity.getMethod().invoke(t, new Object[] {});
|
||||
if (list != null && list.size() > maxHeight) {
|
||||
maxHeight = list.size();
|
||||
}
|
||||
}
|
||||
}
|
||||
return maxHeight;
|
||||
|
||||
}
|
||||
|
||||
public Workbook createExcleByTemplate(TemplateExportParams params, Class<?> pojoClass, Collection<?> dataSet, Map<String, Object> map) {
|
||||
// step 1. 判断模板的地址
|
||||
if (params == null || map == null || StringUtils.isEmpty(params.getTemplateUrl())) {
|
||||
throw new ExcelExportException(ExcelExportEnum.PARAMETER_ERROR);
|
||||
}
|
||||
Workbook wb = null;
|
||||
// step 2. 判断模板的Excel类型,解析模板
|
||||
try {
|
||||
this.teplateParams = params;
|
||||
wb = getCloneWorkBook();
|
||||
// 创建表格样式
|
||||
setExcelExportStyler((IExcelExportStyler) teplateParams.getStyle().getConstructor(Workbook.class).newInstance(wb));
|
||||
// step 3. 解析模板
|
||||
for (int i = 0, le = params.isScanAllsheet() ? wb.getNumberOfSheets() : params.getSheetNum().length; i < le; i++) {
|
||||
if (params.getSheetName() != null && params.getSheetName().length > i && StringUtils.isNotEmpty(params.getSheetName()[i])) {
|
||||
wb.setSheetName(i, params.getSheetName()[i]);
|
||||
}
|
||||
tempCreateCellSet.clear();
|
||||
parseTemplate(wb.getSheetAt(i), map);
|
||||
}
|
||||
if (dataSet != null) {
|
||||
// step 4. 正常的数据填充
|
||||
dataHanlder = params.getDataHanlder();
|
||||
if (dataHanlder != null) {
|
||||
needHanlderList = Arrays.asList(dataHanlder.getNeedHandlerFields());
|
||||
}
|
||||
addDataToSheet(pojoClass, dataSet, wb.getSheetAt(params.getDataSheetNum()), wb);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
return null;
|
||||
}
|
||||
return wb;
|
||||
}
|
||||
|
||||
/**
|
||||
* 克隆excel防止操作原对象,workbook无法克隆,只能对excel进行克隆
|
||||
*
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
private Workbook getCloneWorkBook() throws Exception {
|
||||
return ExcelCache.getWorkbook(teplateParams.getTemplateUrl(), teplateParams.getSheetNum(), teplateParams.isScanAllsheet());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取表头数据,设置表头的序号
|
||||
*
|
||||
* @param sheet
|
||||
* @return
|
||||
*/
|
||||
private Map<String, Integer> getTitleMap(Sheet sheet) {
|
||||
Row row = null;
|
||||
Iterator<Cell> cellTitle;
|
||||
Map<String, Integer> titlemap = new HashMap<String, Integer>();
|
||||
for (int j = 0; j < teplateParams.getHeadingRows(); j++) {
|
||||
row = sheet.getRow(j + teplateParams.getHeadingStartRow());
|
||||
cellTitle = row.cellIterator();
|
||||
int i = row.getFirstCellNum();
|
||||
while (cellTitle.hasNext()) {
|
||||
Cell cell = cellTitle.next();
|
||||
String value = cell.getStringCellValue();
|
||||
if (!StringUtils.isEmpty(value)) {
|
||||
titlemap.put(value, i);
|
||||
}
|
||||
i = i + 1;
|
||||
}
|
||||
}
|
||||
return titlemap;
|
||||
|
||||
}
|
||||
|
||||
private void parseTemplate(Sheet sheet, Map<String, Object> map) throws Exception {
|
||||
deleteCell(sheet, map);
|
||||
Row row = null;
|
||||
int index = 0;
|
||||
while (index <= sheet.getLastRowNum()) {
|
||||
row = sheet.getRow(index++);
|
||||
if (row == null) {
|
||||
continue;
|
||||
}
|
||||
for (int i = row.getFirstCellNum(); i < row.getLastCellNum(); i++) {
|
||||
if (row.getCell(i) != null && !tempCreateCellSet.contains(row.getRowNum() + "_" + row.getCell(i).getColumnIndex())) {
|
||||
setValueForCellByMap(row.getCell(i), map);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 先判断删除,省得影响效率
|
||||
*
|
||||
* @param sheet
|
||||
* @param map
|
||||
* @throws Exception
|
||||
*/
|
||||
private void deleteCell(Sheet sheet, Map<String, Object> map) throws Exception {
|
||||
Row row = null;
|
||||
Cell cell = null;
|
||||
int index = 0;
|
||||
while (index <= sheet.getLastRowNum()) {
|
||||
row = sheet.getRow(index++);
|
||||
if (row == null) {
|
||||
continue;
|
||||
}
|
||||
for (int i = row.getFirstCellNum(); i < row.getLastCellNum(); i++) {
|
||||
cell = row.getCell(i);
|
||||
if (row.getCell(i) != null && (cell.getCellType() == Cell.CELL_TYPE_STRING || cell.getCellType() == Cell.CELL_TYPE_NUMERIC)) {
|
||||
cell.setCellType(Cell.CELL_TYPE_STRING);
|
||||
String text = cell.getStringCellValue();
|
||||
if (text.contains(IF_DELETE)) {
|
||||
if (Boolean.valueOf(eval(text.substring(text.indexOf(START_STR) + 2, text.indexOf(END_STR)).trim(), map).toString())) {
|
||||
PoiSheetUtility.deleteColumn(sheet, i);
|
||||
}
|
||||
cell.setCellValue("");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 给每个Cell通过解析方式set值
|
||||
*
|
||||
* @param cell
|
||||
* @param map
|
||||
*/
|
||||
private void setValueForCellByMap(Cell cell, Map<String, Object> map) throws Exception {
|
||||
int cellType = cell.getCellType();
|
||||
if (cellType != Cell.CELL_TYPE_STRING && cellType != Cell.CELL_TYPE_NUMERIC) {
|
||||
return;
|
||||
}
|
||||
String oldString;
|
||||
cell.setCellType(Cell.CELL_TYPE_STRING);
|
||||
oldString = cell.getStringCellValue();
|
||||
if (oldString != null && oldString.indexOf(START_STR) != -1 && !oldString.contains(FOREACH)) {
|
||||
// step 2. 判断是否含有解析函数
|
||||
String params = null;
|
||||
boolean isNumber = false;
|
||||
if (isNumber(oldString)) {
|
||||
isNumber = true;
|
||||
oldString = oldString.replace(NUMBER_SYMBOL, "");
|
||||
}
|
||||
while (oldString.indexOf(START_STR) != -1) {
|
||||
params = oldString.substring(oldString.indexOf(START_STR) + 2, oldString.indexOf(END_STR));
|
||||
|
||||
oldString = oldString.replace(START_STR + params + END_STR, eval(params, map).toString());
|
||||
}
|
||||
// 如何是数值 类型,就按照数值类型进行设置
|
||||
if (isNumber && StringUtils.isNotBlank(oldString)) {
|
||||
cell.setCellValue(Double.parseDouble(oldString));
|
||||
cell.setCellType(Cell.CELL_TYPE_NUMERIC);
|
||||
} else {
|
||||
cell.setCellValue(oldString);
|
||||
}
|
||||
}
|
||||
// 判断foreach 这种方法
|
||||
if (oldString != null && oldString.contains(FOREACH)) {
|
||||
addListDataToExcel(cell, map, oldString.trim());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private boolean isNumber(String text) {
|
||||
return text.startsWith(NUMBER_SYMBOL) || text.contains("{" + NUMBER_SYMBOL) || text.contains(" " + NUMBER_SYMBOL);
|
||||
}
|
||||
|
||||
/**
|
||||
* 利用foreach循环输出数据
|
||||
*
|
||||
* @param cell
|
||||
* @param map
|
||||
* @param name
|
||||
* @throws Exception
|
||||
*/
|
||||
private void addListDataToExcel(Cell cell, Map<String, Object> map, String name) throws Exception {
|
||||
boolean isCreate = !name.contains(FOREACH_NOT_CREATE);
|
||||
boolean isShift = name.contains(FOREACH_AND_SHIFT);
|
||||
name = name.replace(FOREACH_NOT_CREATE, EMPTY).replace(FOREACH_AND_SHIFT, EMPTY).replace(FOREACH, EMPTY).replace(START_STR, EMPTY);
|
||||
String[] keys = name.replaceAll("\\s{1,}", " ").trim().split(" ");
|
||||
Collection<?> datas = (Collection<?>) PoiPublicUtil.getParamsValue(keys[0], map);
|
||||
List<ExcelTemplateParams> columns = getAllDataColumns(cell, name.replace(keys[0], EMPTY));
|
||||
if (datas == null) {
|
||||
return;
|
||||
}
|
||||
Iterator<?> its = datas.iterator();
|
||||
Row row;
|
||||
int rowIndex = cell.getRow().getRowNum() + 1;
|
||||
// 处理当前行
|
||||
if (its.hasNext()) {
|
||||
Object t = its.next();
|
||||
cell.getRow().setHeight(columns.get(0).getHeight());
|
||||
setForEeachCellValue(isCreate, cell.getRow(), cell.getColumnIndex(), t, columns, map);
|
||||
}
|
||||
if (isShift) {
|
||||
cell.getRow().getSheet().shiftRows(cell.getRowIndex() + 1, cell.getRow().getSheet().getLastRowNum(), datas.size() - 1, true, true);
|
||||
}
|
||||
while (its.hasNext()) {
|
||||
Object t = its.next();
|
||||
if (isCreate) {
|
||||
row = cell.getRow().getSheet().createRow(rowIndex++);
|
||||
} else {
|
||||
row = cell.getRow().getSheet().getRow(rowIndex++);
|
||||
if (row == null) {
|
||||
row = cell.getRow().getSheet().createRow(rowIndex - 1);
|
||||
}
|
||||
}
|
||||
row.setHeight(columns.get(0).getHeight());
|
||||
setForEeachCellValue(isCreate, row, cell.getColumnIndex(), t, columns, map);
|
||||
}
|
||||
}
|
||||
|
||||
private void setForEeachCellValue(boolean isCreate, Row row, int columnIndex, Object t, List<ExcelTemplateParams> columns, Map<String, Object> map) throws Exception {
|
||||
for (int i = 0, max = columnIndex + columns.size(); i < max; i++) {
|
||||
if (row.getCell(i) == null)
|
||||
row.createCell(i);
|
||||
}
|
||||
for (int i = 0, max = columns.size(); i < max; i++) {
|
||||
boolean isNumber = false;
|
||||
String tempStr = new String(columns.get(i).getName());
|
||||
if (isNumber(tempStr)) {
|
||||
isNumber = true;
|
||||
tempStr = tempStr.replace(NUMBER_SYMBOL, "");
|
||||
}
|
||||
map.put(teplateParams.getTempParams(), t);
|
||||
String val = eval(tempStr, map).toString();
|
||||
if (isNumber && StringUtils.isNotEmpty(val)) {
|
||||
row.getCell(i + columnIndex).setCellValue(Double.parseDouble(val));
|
||||
row.getCell(i + columnIndex).setCellType(Cell.CELL_TYPE_NUMERIC);
|
||||
} else {
|
||||
row.getCell(i + columnIndex).setCellValue(val);
|
||||
}
|
||||
row.getCell(i + columnIndex).setCellStyle(columns.get(i).getCellStyle());
|
||||
tempCreateCellSet.add(row.getRowNum() + "_" + (i + columnIndex));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取迭代的数据的值
|
||||
*
|
||||
* @param cell
|
||||
* @param name
|
||||
* @return
|
||||
*/
|
||||
private List<ExcelTemplateParams> getAllDataColumns(Cell cell, String name) {
|
||||
List<ExcelTemplateParams> columns = new ArrayList<ExcelTemplateParams>();
|
||||
cell.setCellValue("");
|
||||
if (name.contains(END_STR)) {
|
||||
columns.add(new ExcelTemplateParams(name.replace(END_STR, EMPTY).trim(), cell.getCellStyle(), cell.getRow().getHeight()));
|
||||
return columns;
|
||||
}
|
||||
columns.add(new ExcelTemplateParams(name.trim(), cell.getCellStyle(), cell.getRow().getHeight()));
|
||||
int index = cell.getColumnIndex();
|
||||
Cell tempCell;
|
||||
while (true) {
|
||||
tempCell = cell.getRow().getCell(++index);
|
||||
if (tempCell == null) {
|
||||
break;
|
||||
}
|
||||
String cellStringString;
|
||||
try {// 允许为空,单表示已经完结了,因为可能被删除了
|
||||
cellStringString = tempCell.getStringCellValue();
|
||||
if (StringUtils.isBlank(cellStringString)) {
|
||||
break;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new ExcelExportException("for each 当中存在空字符串,请检查模板");
|
||||
}
|
||||
// 把读取过的cell 置为空
|
||||
tempCell.setCellValue("");
|
||||
if (cellStringString.contains(END_STR)) {
|
||||
columns.add(new ExcelTemplateParams(cellStringString.trim().replace(END_STR, ""), tempCell.getCellStyle(), tempCell.getRow().getHeight()));
|
||||
break;
|
||||
} else {
|
||||
if (cellStringString.trim().contains(teplateParams.getTempParams())) {
|
||||
columns.add(new ExcelTemplateParams(cellStringString.trim(), tempCell.getCellStyle(), tempCell.getRow().getHeight()));
|
||||
} else {
|
||||
// 最后一行被删除了
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* 对导出序列进行排序和塞选
|
||||
*
|
||||
* @param excelParams
|
||||
* @param titlemap
|
||||
* @return
|
||||
*/
|
||||
private void sortAndFilterExportField(List<ExcelExportEntity> excelParams, Map<String, Integer> titlemap) {
|
||||
for (int i = excelParams.size() - 1; i >= 0; i--) {
|
||||
if (excelParams.get(i).getList() != null && excelParams.get(i).getList().size() > 0) {
|
||||
sortAndFilterExportField(excelParams.get(i).getList(), titlemap);
|
||||
if (excelParams.get(i).getList().size() == 0) {
|
||||
excelParams.remove(i);
|
||||
} else {
|
||||
excelParams.get(i).setOrderNum(i);
|
||||
}
|
||||
} else {
|
||||
if (titlemap.containsKey(excelParams.get(i).getName())) {
|
||||
excelParams.get(i).setOrderNum(i);
|
||||
} else {
|
||||
excelParams.remove(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
sortAllParams(excelParams);
|
||||
}
|
||||
|
||||
}
|
||||
+191
@@ -0,0 +1,191 @@
|
||||
package com.pig4cloud.pigx.common.poi.excel.html;
|
||||
|
||||
import java.util.Formatter;
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.apache.poi.ss.usermodel.Cell;
|
||||
import org.apache.poi.ss.usermodel.CellStyle;
|
||||
import org.apache.poi.ss.usermodel.Row;
|
||||
import org.apache.poi.ss.usermodel.Sheet;
|
||||
import org.apache.poi.ss.usermodel.Workbook;
|
||||
import com.pig4cloud.pigx.common.poi.excel.html.helper.CellValueHelper;
|
||||
import com.pig4cloud.pigx.common.poi.excel.html.helper.MergedRegionHelper;
|
||||
import com.pig4cloud.pigx.common.poi.excel.html.helper.StylerHelper;
|
||||
|
||||
/**
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
* Excel转换成Html 服务
|
||||
*/
|
||||
public class ExcelToHtmlServer {
|
||||
|
||||
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 static final String COL_HEAD_CLASS = "colHeader";
|
||||
// private static final String ROW_HEAD_CLASS = "rowHeader";
|
||||
|
||||
private static final String DEFAULTS_CLASS = "excelDefaults";
|
||||
|
||||
public ExcelToHtmlServer(Workbook wb, boolean completeHTML, int sheetNum) {
|
||||
this.wb = wb;
|
||||
this.completeHTML = completeHTML;
|
||||
this.sheetNum = sheetNum;
|
||||
cssRandom = (int) Math.ceil(Math.random() * 1000);
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
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();
|
||||
} finally {
|
||||
if (out != null)
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
|
||||
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 (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");
|
||||
}
|
||||
|
||||
private String styleName(CellStyle style) {
|
||||
if (style == null)
|
||||
return "";
|
||||
return String.format("style_%02x_%s font_%s_%s", style.getIndex(), cssRandom, style.getFontIndex(), cssRandom);
|
||||
}
|
||||
}
|
||||
+134
@@ -0,0 +1,134 @@
|
||||
package com.pig4cloud.pigx.common.poi.excel.html.helper;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
import org.apache.poi.ss.usermodel.Cell;
|
||||
import org.apache.poi.ss.usermodel.Font;
|
||||
import org.apache.poi.ss.usermodel.Workbook;
|
||||
import org.apache.poi.xssf.usermodel.XSSFFont;
|
||||
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
|
||||
import com.google.common.xml.XmlEscapers;
|
||||
|
||||
/**
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
* Cell值帮助类
|
||||
*/
|
||||
public class CellValueHelper {
|
||||
/**
|
||||
* Excel 格式
|
||||
*/
|
||||
private boolean is07;
|
||||
|
||||
private int cssRandom;
|
||||
|
||||
private Map<String, String> fontCache = new HashMap<String, String>();
|
||||
|
||||
public CellValueHelper(Workbook wb, int cssRandom) {
|
||||
this.cssRandom = cssRandom;
|
||||
if (wb instanceof HSSFWorkbook)
|
||||
is07 = false;
|
||||
else if (wb instanceof XSSFWorkbook) {
|
||||
is07 = true;
|
||||
cacheFontInfo(wb);
|
||||
} else
|
||||
throw new IllegalArgumentException("unknown workbook type: " + wb.getClass().getSimpleName());
|
||||
}
|
||||
|
||||
/**
|
||||
* O7 版本坑爹bug
|
||||
*
|
||||
* @param wb
|
||||
*/
|
||||
private void cacheFontInfo(Workbook wb) {
|
||||
for (short i = 0, le = wb.getNumberOfFonts(); i < le; i++) {
|
||||
Font font = wb.getFontAt(i);
|
||||
fontCache.put(font.getBoldweight() + "_" + font.getItalic() + "_" + font.getFontName() + "_" + font.getFontHeightInPoints() + "_" + font.getColor(), font.getIndex() + "");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public String getHtmlValue(Cell cell) {
|
||||
if (Cell.CELL_TYPE_BOOLEAN == cell.getCellType() || Cell.CELL_TYPE_NUMERIC == cell.getCellType()) {
|
||||
cell.setCellType(Cell.CELL_TYPE_STRING);
|
||||
return cell.getStringCellValue();
|
||||
} else if (Cell.CELL_TYPE_STRING == cell.getCellType()) {
|
||||
if (cell.getRichStringCellValue().numFormattingRuns() == 0) {
|
||||
return XmlEscapers.xmlContentEscaper().escape(cell.getStringCellValue());
|
||||
} else if (is07) {
|
||||
return getXSSFRichString((XSSFRichTextString) cell.getRichStringCellValue());
|
||||
} else {
|
||||
return getHSSFRichString((HSSFRichTextString) cell.getRichStringCellValue());
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* 03版本复杂数据
|
||||
*
|
||||
* @param rich
|
||||
* @return
|
||||
*/
|
||||
private String getHSSFRichString(HSSFRichTextString rich) {
|
||||
int nums = rich.numFormattingRuns();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String text = rich.toString();
|
||||
int currentIndex = 0;
|
||||
sb.append(text.substring(0, rich.getIndexOfFormattingRun(0)));
|
||||
for (int i = 0; i < nums; i++) {
|
||||
sb.append("<span ");
|
||||
sb.append("class='font_" + rich.getFontOfFormattingRun(i));
|
||||
sb.append("_");
|
||||
sb.append(cssRandom);
|
||||
sb.append("'>");
|
||||
currentIndex = rich.getIndexOfFormattingRun(i);
|
||||
if (i < nums - 1) {
|
||||
sb.append(XmlEscapers.xmlContentEscaper().escape(text.substring(currentIndex, rich.getIndexOfFormattingRun(i + 1))));
|
||||
} else {
|
||||
sb.append(XmlEscapers.xmlContentEscaper().escape(text.substring(currentIndex, text.length())));
|
||||
}
|
||||
sb.append("</span>");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 07版本复杂数据
|
||||
*
|
||||
* @param rich
|
||||
* @return
|
||||
*/
|
||||
private String getXSSFRichString(XSSFRichTextString rich) {
|
||||
int nums = rich.numFormattingRuns();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String text = rich.toString();
|
||||
int currentIndex = 0, lastIndex = 0;
|
||||
for (int i = 1; i <= nums; i++) {
|
||||
sb.append("<span ");
|
||||
try {
|
||||
sb.append("class='font_" + getFontIndex(rich.getFontOfFormattingRun(i - 1)));
|
||||
sb.append("_");
|
||||
sb.append(cssRandom);
|
||||
sb.append("'");
|
||||
} catch (Exception e) {
|
||||
}
|
||||
sb.append(">");
|
||||
currentIndex = rich.getIndexOfFormattingRun(i) == -1 ? text.length() : rich.getIndexOfFormattingRun(i);
|
||||
sb.append(XmlEscapers.xmlContentEscaper().escape(text.substring(lastIndex, currentIndex)));
|
||||
sb.append("</span>");
|
||||
lastIndex = currentIndex;
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private String getFontIndex(XSSFFont font) {
|
||||
return fontCache.get(font.getBoldweight() + "_" + font.getItalic() + "_" + font.getFontName() + "_" + font.getFontHeightInPoints() + "_" + font.getColor());
|
||||
}
|
||||
}
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
package com.pig4cloud.pigx.common.poi.excel.html.helper;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.poi.ss.usermodel.Sheet;
|
||||
|
||||
/**
|
||||
* 合并单元格帮助类
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
*/
|
||||
public class MergedRegionHelper {
|
||||
|
||||
private Map<String, Integer[]> mergedCache = new HashMap<String, Integer[]>();
|
||||
|
||||
private Set<String> notNeedCread = new HashSet<String>();
|
||||
|
||||
public MergedRegionHelper(Sheet sheet) {
|
||||
getAllMergedRegion(sheet);
|
||||
}
|
||||
|
||||
private void getAllMergedRegion(Sheet sheet) {
|
||||
int nums = sheet.getNumMergedRegions();
|
||||
for (int i = 0; i < nums; i++) {
|
||||
handerMergedString(sheet.getMergedRegion(i).formatAsString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据合并输出内容,处理合并单元格事情
|
||||
*
|
||||
* @param formatAsString
|
||||
*/
|
||||
private void handerMergedString(String formatAsString) {
|
||||
String[] strArr = formatAsString.split(":");
|
||||
if (strArr.length == 2) {
|
||||
int startCol = strArr[0].charAt(0) - 65;
|
||||
if (strArr[0].charAt(1) >= 65) {
|
||||
startCol = (startCol + 1) * 26 + (strArr[0].charAt(1) - 65);
|
||||
}
|
||||
int startRol = Integer.valueOf(strArr[0].substring(strArr[0].charAt(1) >= 65 ? 2 : 1));
|
||||
int endCol = strArr[1].charAt(0) - 65;
|
||||
if (strArr[1].charAt(1) >= 65) {
|
||||
endCol = (endCol + 1) * 26 + (strArr[1].charAt(1) - 65);
|
||||
}
|
||||
int endRol = Integer.valueOf(strArr[1].substring(strArr[1].charAt(1) >= 65 ? 2 : 1));
|
||||
mergedCache.put(startRol + "_" + startCol, new Integer[] { endRol - startRol + 1, endCol - startCol + 1 });
|
||||
for (int i = startRol; i <= endRol; i++) {
|
||||
for (int j = startCol; j <= endCol; j++) {
|
||||
notNeedCread.add(i + "_" + j);
|
||||
}
|
||||
}
|
||||
notNeedCread.remove(startRol + "_" + startCol);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 是不是需要创建这个TD
|
||||
*
|
||||
* @param row
|
||||
* @param col
|
||||
* @return
|
||||
*/
|
||||
public boolean isNeedCreate(int row, int col) {
|
||||
return !notNeedCread.contains(row + "_" + col);
|
||||
}
|
||||
|
||||
/**
|
||||
* 是不是合并区域
|
||||
*
|
||||
* @param row
|
||||
* @param col
|
||||
* @return
|
||||
*/
|
||||
public boolean isMergedRegion(int row, int col) {
|
||||
return mergedCache.containsKey(row + "_" + col);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取合并区域
|
||||
*
|
||||
* @param row
|
||||
* @param col
|
||||
* @return
|
||||
*/
|
||||
public Integer[] getRowAndColSpan(int row, int col) {
|
||||
return mergedCache.get(row + "_" + col);
|
||||
}
|
||||
|
||||
}
|
||||
+271
@@ -0,0 +1,271 @@
|
||||
package com.pig4cloud.pigx.common.poi.excel.html.helper;
|
||||
|
||||
import static org.apache.poi.ss.usermodel.CellStyle.ALIGN_CENTER;
|
||||
import static org.apache.poi.ss.usermodel.CellStyle.ALIGN_CENTER_SELECTION;
|
||||
import static org.apache.poi.ss.usermodel.CellStyle.ALIGN_FILL;
|
||||
import static org.apache.poi.ss.usermodel.CellStyle.ALIGN_JUSTIFY;
|
||||
import static org.apache.poi.ss.usermodel.CellStyle.ALIGN_LEFT;
|
||||
import static org.apache.poi.ss.usermodel.CellStyle.ALIGN_RIGHT;
|
||||
import static org.apache.poi.ss.usermodel.CellStyle.VERTICAL_BOTTOM;
|
||||
import static org.apache.poi.ss.usermodel.CellStyle.VERTICAL_CENTER;
|
||||
import static org.apache.poi.ss.usermodel.CellStyle.VERTICAL_TOP;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.Formatter;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
|
||||
import org.apache.poi.hssf.usermodel.HSSFPalette;
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
import org.apache.poi.hssf.util.HSSFColor;
|
||||
import org.apache.poi.ss.usermodel.Cell;
|
||||
import org.apache.poi.ss.usermodel.CellStyle;
|
||||
import org.apache.poi.ss.usermodel.Color;
|
||||
import org.apache.poi.ss.usermodel.Font;
|
||||
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.XSSFCellStyle;
|
||||
import org.apache.poi.xssf.usermodel.XSSFColor;
|
||||
import org.apache.poi.xssf.usermodel.XSSFFont;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
import com.pig4cloud.pigx.common.poi.util.PoiPublicUtil;
|
||||
|
||||
/**
|
||||
* 样式帮助类
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
*/
|
||||
public class StylerHelper {
|
||||
|
||||
private static String DEFAULTS_CLASS_CSS = ".excelDefaults {background-color: white;color: black;text-decoration: none;direction: ltr;text-transform: none;text-indent: 0;letter-spacing: 0;word-spacing: 0;white-space: normal;unicode-bidi: normal;vertical-align: 0;text-shadow: none;padding: 0;margin: 0;border-collapse: collapse;white-space: pre-wrap;word-wrap: break-word;word-break: break-all;}.excelDefaults td {padding: 1px 5px;border: 1px solid silver;border-color: #000000;text-align: center;vertical-align: middle;font-size: 12pt;}.excelDefaults .colHeader {background-color: silver;font-weight: bold;border: 1px solid black;text-align: center;padding: 1px 5px;}.excelDefaults .rowHeader {background-color: silver;font-weight: bold;border: 1px solid black;text-align: right;padding: 1px 5px;}";
|
||||
|
||||
private static final String DEFAULTS_CLASS = "excelDefaults";
|
||||
|
||||
private static final Map<Short, String> ALIGN = PoiPublicUtil.mapFor(ALIGN_LEFT, "left", ALIGN_CENTER, "center", ALIGN_RIGHT, "right", ALIGN_FILL, "left", ALIGN_JUSTIFY, "left", ALIGN_CENTER_SELECTION, "center");
|
||||
|
||||
private static final Map<Short, String> VERTICAL_ALIGN = PoiPublicUtil.mapFor(VERTICAL_BOTTOM, "bottom", VERTICAL_CENTER, "middle", VERTICAL_TOP, "top");
|
||||
|
||||
private Formatter out;
|
||||
|
||||
private Sheet sheet;
|
||||
|
||||
private HtmlHelper helper;
|
||||
|
||||
private int sheetNum;
|
||||
|
||||
private int cssRandom;
|
||||
|
||||
public StylerHelper(Workbook wb, Formatter out, int sheetNum, int cssRandom) {
|
||||
this.out = out;
|
||||
this.sheetNum = sheetNum;
|
||||
this.cssRandom = cssRandom;
|
||||
if (wb instanceof HSSFWorkbook)
|
||||
helper = new HSSFHtmlHelper((HSSFWorkbook) wb);
|
||||
else if (wb instanceof XSSFWorkbook)
|
||||
helper = new XSSFHtmlHelper((XSSFWorkbook) wb);
|
||||
else
|
||||
throw new IllegalArgumentException("unknown workbook type: " + wb.getClass().getSimpleName());
|
||||
printInlineStyle(wb);
|
||||
}
|
||||
|
||||
private void printInlineStyle(Workbook wb) {
|
||||
out.format("<style type=\"text/css\">%n");
|
||||
printStyles(wb);
|
||||
prontFonts(wb);
|
||||
out.format("</style>%n");
|
||||
}
|
||||
|
||||
private void prontFonts(Workbook wb) {
|
||||
for (short i = 0, le = wb.getNumberOfFonts(); i <= le; i++) {
|
||||
Font font = wb.getFontAt(i);
|
||||
out.format(".%s .%s {%n", DEFAULTS_CLASS, "font_" + i + "_" + cssRandom);
|
||||
fontStyle(font);
|
||||
out.format("}%n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void printStyles(Workbook wb) {
|
||||
if (DEFAULTS_CLASS_CSS == null) {
|
||||
DEFAULTS_CLASS_CSS = getDefaultsClassCss();
|
||||
}
|
||||
out.format(DEFAULTS_CLASS_CSS);
|
||||
Set<CellStyle> seen = new HashSet<CellStyle>();
|
||||
sheet = wb.getSheetAt(sheetNum);
|
||||
Iterator<Row> rows = sheet.rowIterator();
|
||||
while (rows.hasNext()) {
|
||||
Row row = rows.next();
|
||||
for (Cell cell : row) {
|
||||
CellStyle style = cell.getCellStyle();
|
||||
if (!seen.contains(style)) {
|
||||
printStyle(style);
|
||||
seen.add(style);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String getDefaultsClassCss() {
|
||||
BufferedReader in = null;
|
||||
StringBuilder sb = new StringBuilder();
|
||||
Formatter formatter = new Formatter(sb);
|
||||
try {
|
||||
in = new BufferedReader(new InputStreamReader(StylerHelper.class.getResourceAsStream("excelStyle.css")));
|
||||
String line;
|
||||
while ((line = in.readLine()) != null) {
|
||||
formatter.format("%s%n", line);
|
||||
}
|
||||
return formatter.toString();
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException("Reading standard css", e);
|
||||
} finally {
|
||||
if (in != null) {
|
||||
try {
|
||||
in.close();
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException("Reading standard css", e);
|
||||
}
|
||||
}
|
||||
formatter.close();
|
||||
}
|
||||
}
|
||||
|
||||
private void printStyle(CellStyle style) {
|
||||
out.format(".%s .%s {%n", DEFAULTS_CLASS, styleName(style));
|
||||
styleContents(style);
|
||||
out.format("}%n");
|
||||
}
|
||||
|
||||
private void styleContents(CellStyle style) {
|
||||
if (style.getAlignment() != 2) {
|
||||
styleOut("text-align", style.getAlignment(), ALIGN);
|
||||
styleOut("vertical-align", style.getAlignment(), VERTICAL_ALIGN);
|
||||
}
|
||||
helper.colorStyles(style, out);
|
||||
}
|
||||
|
||||
private void fontStyle(Font font) {
|
||||
if (font.getBoldweight() >= Font.BOLDWEIGHT_BOLD)
|
||||
out.format(" font-weight: bold;%n");
|
||||
if (font.getItalic())
|
||||
out.format(" font-style: italic;%n");
|
||||
out.format(" font-family: %s;%n", font.getFontName());
|
||||
|
||||
int fontheight = font.getFontHeightInPoints();
|
||||
if (fontheight == 9) {
|
||||
fontheight = 10;
|
||||
}
|
||||
out.format(" font-size: %dpt;%n", fontheight);
|
||||
helper.styleColor(out, "color", getColor(font));
|
||||
}
|
||||
|
||||
private Color getColor(Font font) {
|
||||
if (helper instanceof HSSFHtmlHelper) {
|
||||
return ((HSSFWorkbook) sheet.getWorkbook()).getCustomPalette().getColor(font.getColor());
|
||||
} else {
|
||||
return ((XSSFFont) font).getXSSFColor();
|
||||
}
|
||||
}
|
||||
|
||||
private String styleName(CellStyle style) {
|
||||
if (style == null)
|
||||
return "";
|
||||
return String.format("style_%02x_%s", style.getIndex(), cssRandom);
|
||||
}
|
||||
|
||||
private <K> void styleOut(String attr, K key, Map<K, String> mapping) {
|
||||
String value = mapping.get(key);
|
||||
if (value != null) {
|
||||
out.format(" %s: %s;%n", attr, value);
|
||||
}
|
||||
}
|
||||
|
||||
private interface HtmlHelper {
|
||||
/**
|
||||
* Outputs the appropriate CSS style for the given cell style.
|
||||
*
|
||||
* @param style
|
||||
* The cell style.
|
||||
* @param out
|
||||
* The place to write the output.
|
||||
*/
|
||||
void colorStyles(CellStyle style, Formatter out);
|
||||
|
||||
void styleColor(Formatter out, String attr, Color color);
|
||||
}
|
||||
|
||||
private class HSSFHtmlHelper implements HtmlHelper {
|
||||
private final HSSFWorkbook wb;
|
||||
private final HSSFPalette colors;
|
||||
|
||||
private HSSFColor HSSF_AUTO = new HSSFColor.AUTOMATIC();
|
||||
|
||||
public HSSFHtmlHelper(HSSFWorkbook wb) {
|
||||
this.wb = wb;
|
||||
colors = wb.getCustomPalette();
|
||||
}
|
||||
|
||||
public void colorStyles(CellStyle style, Formatter out) {
|
||||
HSSFCellStyle cs = (HSSFCellStyle) style;
|
||||
out.format(" /* fill pattern = %d */%n", cs.getFillPattern());
|
||||
styleColor(out, "background-color", cs.getFillForegroundColor());
|
||||
styleColor(out, "color", colors.getColor(cs.getFont(wb).getColor()));
|
||||
}
|
||||
|
||||
private void styleColor(Formatter out, String attr, short index) {
|
||||
HSSFColor color = colors.getColor(index);
|
||||
if (index == HSSF_AUTO.getIndex() || color == null) {
|
||||
out.format(" /* %s: index = %d */%n", attr, index);
|
||||
} else {
|
||||
short[] rgb = color.getTriplet();
|
||||
out.format(" %s: #%02x%02x%02x; /* index = %d */%n", attr, rgb[0], rgb[1], rgb[2], index);
|
||||
}
|
||||
}
|
||||
|
||||
public void styleColor(Formatter out, String attr, Color color) {
|
||||
if (color == null) {
|
||||
return;
|
||||
}
|
||||
HSSFColor hSSFColor = (HSSFColor) color;
|
||||
short[] rgb = hSSFColor.getTriplet();
|
||||
out.format(" %s: #%02x%02x%02x; %n", attr, rgb[0], rgb[1], rgb[2]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of {@link HtmlHelper} for XSSF files.
|
||||
*
|
||||
* @author Ken Arnold, Industrious Media LLC
|
||||
*/
|
||||
private class XSSFHtmlHelper implements HtmlHelper {
|
||||
|
||||
public XSSFHtmlHelper(XSSFWorkbook wb) {
|
||||
}
|
||||
|
||||
public void colorStyles(CellStyle style, Formatter out) {
|
||||
XSSFCellStyle cs = (XSSFCellStyle) style;
|
||||
styleColor(out, "background-color", cs.getFillForegroundXSSFColor());
|
||||
styleColor(out, "color", cs.getFont().getXSSFColor());
|
||||
}
|
||||
|
||||
public void styleColor(Formatter out, String attr, Color color) {
|
||||
XSSFColor xSSFColor = (XSSFColor) color;
|
||||
if (color == null || xSSFColor.isAuto())
|
||||
return;
|
||||
|
||||
byte[] rgb = xSSFColor.getRGB();
|
||||
if (rgb == null) {
|
||||
return;
|
||||
}
|
||||
out.format(" %s: #%02x%02x%02x;%n", attr, rgb[0], rgb[1], rgb[2]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
.excelDefaults {
|
||||
background-color: white;
|
||||
color: black;
|
||||
text-decoration: none;
|
||||
direction: ltr;
|
||||
text-transform: none;
|
||||
text-indent: 0;
|
||||
letter-spacing: 0;
|
||||
word-spacing: 0;
|
||||
white-space: normal;
|
||||
unicode-bidi: normal;
|
||||
vertical-align: 0;
|
||||
text-shadow: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
border-collapse: collapse;
|
||||
white-space: pre-wrap;
|
||||
word-wrap: break-word;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.excelDefaults td {
|
||||
padding: 1px 5px;
|
||||
border: 1px solid silver;
|
||||
border-color: #000000;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
font-size: 12pt;
|
||||
}
|
||||
|
||||
.excelDefaults .colHeader {
|
||||
background-color: silver;
|
||||
font-weight: bold;
|
||||
border: 1px solid black;
|
||||
text-align: center;
|
||||
padding: 1px 5px;
|
||||
}
|
||||
|
||||
.excelDefaults .rowHeader {
|
||||
background-color: silver;
|
||||
font-weight: bold;
|
||||
border: 1px solid black;
|
||||
text-align: right;
|
||||
padding: 1px 5px;
|
||||
}
|
||||
+278
@@ -0,0 +1,278 @@
|
||||
package com.pig4cloud.pigx.common.poi.excel.imports;
|
||||
|
||||
import com.pig4cloud.pigx.common.poi.excel.entity.params.ExcelImportEntity;
|
||||
import com.pig4cloud.pigx.common.poi.excel.entity.sax.SaxReadCellEntity;
|
||||
import com.pig4cloud.pigx.common.poi.exception.excel.ExcelImportException;
|
||||
import com.pig4cloud.pigx.common.poi.exception.excel.enums.ExcelImportEnum;
|
||||
import com.pig4cloud.pigx.common.poi.handler.inter.IExcelDataHandler;
|
||||
import com.pig4cloud.pigx.common.poi.util.PoiPublicUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.poi.ss.usermodel.Cell;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Type;
|
||||
import java.math.BigDecimal;
|
||||
import java.sql.Time;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
* Cell 取值服务 判断类型处理数据
|
||||
* 1.判断Excel中的类型
|
||||
* 2.根据replace替换值
|
||||
* 3.handler处理数据
|
||||
* 4.判断返回类型转化数据返回
|
||||
*/
|
||||
@Slf4j
|
||||
public class CellValueServer {
|
||||
|
||||
private List<String> hanlderList = null;
|
||||
|
||||
/**
|
||||
* 获取单元格内的值
|
||||
*
|
||||
* @param xclass
|
||||
* @param cell
|
||||
* @param entity
|
||||
* @return
|
||||
*/
|
||||
private Object getCellValue(String xclass, Cell cell, ExcelImportEntity entity) {
|
||||
if (cell == null) {
|
||||
return "";
|
||||
}
|
||||
Object result = null;
|
||||
// 日期格式比较特殊,和cell格式不一致
|
||||
if ("class java.util.Date".equals(xclass) || ("class java.sql.Time").equals(xclass)) {
|
||||
if (Cell.CELL_TYPE_NUMERIC == cell.getCellType()) {
|
||||
// 日期格式
|
||||
result = cell.getDateCellValue();
|
||||
} else {
|
||||
cell.setCellType(Cell.CELL_TYPE_STRING);
|
||||
result = getDateData(entity, cell.getStringCellValue());
|
||||
}
|
||||
if (("class java.sql.Time").equals(xclass)) {
|
||||
result = new Time(((Date) result).getTime());
|
||||
}
|
||||
} else if (Cell.CELL_TYPE_NUMERIC == cell.getCellType()) {
|
||||
result = cell.getNumericCellValue();
|
||||
} else if (Cell.CELL_TYPE_BOOLEAN == cell.getCellType()) {
|
||||
result = cell.getBooleanCellValue();
|
||||
} else {
|
||||
result = cell.getStringCellValue();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取日期类型数据
|
||||
*
|
||||
* @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) {
|
||||
log.error("时间格式化失败,格式化:{},值:{}", entity.getFormat(), value);
|
||||
throw new ExcelImportException(ExcelImportEnum.GET_VALUE_ERROR);
|
||||
}
|
||||
}
|
||||
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,entity.isMultiReplace());
|
||||
}
|
||||
result = hanlderValue(dataHanlder, object, result, titleString);
|
||||
return getValueByType(xclass, result, entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取cell值
|
||||
*
|
||||
* @param dataHanlder
|
||||
* @param object
|
||||
* @param entity
|
||||
* @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,entity.isMultiReplace());
|
||||
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 {
|
||||
//update-begin-author:scott date:20180711 for:TASK #2950 【bug】excel 导入报错,空指针问题
|
||||
if(result==null || "".equals(String.valueOf(result))){
|
||||
return null;
|
||||
}
|
||||
//update-end-author:scott date:20180711 for:TASK #2950 【bug】excel 导入报错,空指针问题
|
||||
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)) {
|
||||
return Long.valueOf(String.valueOf(result));
|
||||
}
|
||||
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)) {
|
||||
return Integer.valueOf(String.valueOf(result));
|
||||
}
|
||||
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) {
|
||||
log.error(e.getMessage(), e);
|
||||
throw new ExcelImportException(ExcelImportEnum.GET_VALUE_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 调用处理接口处理值
|
||||
*
|
||||
* @param dataHanlder
|
||||
* @param object
|
||||
* @param result
|
||||
* @param titleString
|
||||
* @return
|
||||
*/
|
||||
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 excel单元格获取的值
|
||||
* @param multiReplace 是否支持多值替换
|
||||
*/
|
||||
private Object replaceValue(String[] replace, Object result,boolean multiReplace) {
|
||||
if(result == null){
|
||||
return "";
|
||||
}
|
||||
if(replace == null || replace.length<=0){
|
||||
return result;
|
||||
}
|
||||
String temp = String.valueOf(result);
|
||||
String backValue = "";
|
||||
if(temp.indexOf(",")>0 && multiReplace){
|
||||
//原值中带有逗号,认为他是多值的
|
||||
String multiReplaces[] = temp.split(",");
|
||||
for (String str : multiReplaces) {
|
||||
backValue = backValue.concat(replaceSingleValue(replace, str)+",");
|
||||
}
|
||||
if(backValue.equals("")){
|
||||
backValue = temp;
|
||||
}else{
|
||||
backValue = backValue.substring(0, backValue.length()-1);
|
||||
}
|
||||
}else{
|
||||
backValue = replaceSingleValue(replace, temp);
|
||||
}
|
||||
return backValue;
|
||||
}
|
||||
/**
|
||||
* 单值替换 ,若没找到则原值返回
|
||||
*/
|
||||
private String replaceSingleValue(String[] replace, String temp){
|
||||
String[] tempArr;
|
||||
for (int i = 0; i < replace.length; i++) {
|
||||
tempArr = replace[i].split("_");
|
||||
if (temp.equals(tempArr[0])) {
|
||||
return tempArr[1];
|
||||
}
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
}
|
||||
+410
@@ -0,0 +1,410 @@
|
||||
package com.pig4cloud.pigx.common.poi.excel.imports;
|
||||
|
||||
import com.pig4cloud.pigx.common.poi.excel.annotation.ExcelTarget;
|
||||
import com.pig4cloud.pigx.common.poi.excel.entity.ImportParams;
|
||||
import com.pig4cloud.pigx.common.poi.excel.entity.params.ExcelCollectionParams;
|
||||
import com.pig4cloud.pigx.common.poi.excel.entity.params.ExcelImportEntity;
|
||||
import com.pig4cloud.pigx.common.poi.excel.entity.result.ExcelImportResult;
|
||||
import com.pig4cloud.pigx.common.poi.excel.entity.result.ExcelVerifyHanlderResult;
|
||||
import com.pig4cloud.pigx.common.poi.excel.imports.base.ImportBaseService;
|
||||
import com.pig4cloud.pigx.common.poi.excel.imports.verifys.VerifyHandlerServer;
|
||||
import com.pig4cloud.pigx.common.poi.exception.excel.ExcelImportException;
|
||||
import com.pig4cloud.pigx.common.poi.exception.excel.enums.ExcelImportEnum;
|
||||
import com.pig4cloud.pigx.common.poi.util.ExcelUtil;
|
||||
import com.pig4cloud.pigx.common.poi.util.PoiPublicUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.poi.POIXMLDocument;
|
||||
import org.apache.poi.hssf.usermodel.HSSFSheet;
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
import org.apache.poi.openxml4j.opc.OPCPackage;
|
||||
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
|
||||
import org.apache.poi.ss.formula.functions.T;
|
||||
import org.apache.poi.ss.usermodel.*;
|
||||
import org.apache.poi.xssf.usermodel.XSSFSheet;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.PushbackInputStream;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
* Excel 导入服务
|
||||
*/
|
||||
@Slf4j
|
||||
@SuppressWarnings({ "rawtypes", "unchecked", "hiding" })
|
||||
public class ExcelImportServer extends ImportBaseService {
|
||||
|
||||
private CellValueServer cellValueServer;
|
||||
|
||||
private VerifyHandlerServer verifyHandlerServer;
|
||||
|
||||
private boolean verfiyFail = false;
|
||||
/**
|
||||
* 异常数据styler
|
||||
*/
|
||||
private CellStyle errorCellStyle;
|
||||
|
||||
public ExcelImportServer() {
|
||||
this.cellValueServer = new CellValueServer();
|
||||
this.verifyHandlerServer = new VerifyHandlerServer();
|
||||
}
|
||||
|
||||
/***
|
||||
* 向List里面继续添加元素
|
||||
*
|
||||
* @param exclusions
|
||||
* @param object
|
||||
* @param param
|
||||
* @param row
|
||||
* @param titlemap
|
||||
* @param targetId
|
||||
* @param pictures
|
||||
* @param params
|
||||
*/
|
||||
private void addListContinue(Object object, ExcelCollectionParams param, Row row, Map<Integer, String> titlemap, String targetId, Map<String, PictureData> pictures, ImportParams params) throws Exception {
|
||||
Collection collection = (Collection) PoiPublicUtil.getMethod(param.getName(), object.getClass()).invoke(object, new Object[] {});
|
||||
Object entity = PoiPublicUtil.createObject(param.getType(), targetId);
|
||||
String picId;
|
||||
boolean isUsed = false;// 是否需要加上这个对象
|
||||
for (int i = row.getFirstCellNum(); i < row.getLastCellNum(); i++) {
|
||||
Cell cell = row.getCell(i);
|
||||
String titleString = (String) titlemap.get(i);
|
||||
if (param.getExcelParams().containsKey(titleString)) {
|
||||
if (param.getExcelParams().get(titleString).getType() == 2) {
|
||||
picId = row.getRowNum() + "_" + i;
|
||||
saveImage(object, picId, param.getExcelParams(), titleString, pictures, params);
|
||||
} else {
|
||||
saveFieldValue(params, entity, cell, param.getExcelParams(), titleString, row);
|
||||
}
|
||||
isUsed = true;
|
||||
}
|
||||
}
|
||||
if (isUsed) {
|
||||
collection.add(entity);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取key的值,针对不同类型获取不同的值
|
||||
*
|
||||
* @param cell
|
||||
* @return
|
||||
*/
|
||||
private String getKeyValue(Cell cell) {
|
||||
Object obj = null;
|
||||
switch (cell.getCellType()) {
|
||||
case Cell.CELL_TYPE_STRING:
|
||||
obj = cell.getStringCellValue();
|
||||
break;
|
||||
case Cell.CELL_TYPE_BOOLEAN:
|
||||
obj = cell.getBooleanCellValue();
|
||||
break;
|
||||
case Cell.CELL_TYPE_NUMERIC:
|
||||
obj = cell.getNumericCellValue();
|
||||
break;
|
||||
case Cell.CELL_TYPE_FORMULA:
|
||||
obj = cell.getCellFormula();
|
||||
break;
|
||||
}
|
||||
return obj == null ? null : obj.toString().trim();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取保存的真实路径
|
||||
*
|
||||
* @param excelImportEntity
|
||||
* @param object
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
private String getSaveUrl(ExcelImportEntity excelImportEntity, Object object) throws Exception {
|
||||
String url = "";
|
||||
if (excelImportEntity.getSaveUrl().equals("upload")) {
|
||||
if (excelImportEntity.getMethods() != null && excelImportEntity.getMethods().size() > 0) {
|
||||
object = getFieldBySomeMethod(excelImportEntity.getMethods(), object);
|
||||
}
|
||||
url = object.getClass().getName().split("\\.")[object.getClass().getName().split("\\.").length - 1];
|
||||
return excelImportEntity.getSaveUrl() + "/" + url.substring(0, url.lastIndexOf("Entity"));
|
||||
}
|
||||
return excelImportEntity.getSaveUrl();
|
||||
}
|
||||
private <T> List<T> importExcel(Collection<T> result, Sheet sheet, Class<?> pojoClass, ImportParams params, Map<String, PictureData> pictures) throws Exception {
|
||||
List collection = new ArrayList();
|
||||
Map<String, ExcelImportEntity> excelParams = new HashMap<String, ExcelImportEntity>();
|
||||
List<ExcelCollectionParams> excelCollection = new ArrayList<ExcelCollectionParams>();
|
||||
String targetId = null;
|
||||
if (!Map.class.equals(pojoClass)) {
|
||||
Field fileds[] = PoiPublicUtil.getClassFields(pojoClass);
|
||||
ExcelTarget etarget = pojoClass.getAnnotation(ExcelTarget.class);
|
||||
if (etarget != null) {
|
||||
targetId = etarget.value();
|
||||
}
|
||||
getAllExcelField(targetId, fileds, excelParams, excelCollection, pojoClass, null);
|
||||
}
|
||||
Iterator<Row> rows = sheet.rowIterator();
|
||||
Map<Integer, String> titlemap = getTitleMap(sheet, rows, params, excelCollection);
|
||||
Row row = null;
|
||||
//跳过表头和标题行
|
||||
for (int j = 0; j < params.getTitleRows() + params.getHeadRows(); j++) {
|
||||
row = rows.next();
|
||||
}
|
||||
Object object = null;
|
||||
String picId;
|
||||
while (rows.hasNext() && (row == null || sheet.getLastRowNum() - row.getRowNum() > params.getLastOfInvalidRow())) {
|
||||
row = rows.next();
|
||||
// 判断是集合元素还是不是集合元素,如果是就继续加入这个集合,不是就创建新的对象
|
||||
if ((row.getCell(params.getKeyIndex()) == null || StringUtils.isEmpty(getKeyValue(row.getCell(params.getKeyIndex()))))
|
||||
&& object != null && !Map.class.equals(pojoClass)) {
|
||||
for (ExcelCollectionParams param : excelCollection) {
|
||||
addListContinue(object, param, row, titlemap, targetId, pictures, params);
|
||||
}
|
||||
|
||||
} else {
|
||||
object = PoiPublicUtil.createObject(pojoClass, targetId);
|
||||
try {
|
||||
for (int i = row.getFirstCellNum(), le = row.getLastCellNum(); i < le; i++) {
|
||||
Cell cell = row.getCell(i);
|
||||
String titleString = (String) titlemap.get(i);
|
||||
if (excelParams.containsKey(titleString) || Map.class.equals(pojoClass)) {
|
||||
if (excelParams.get(titleString) != null && excelParams.get(titleString).getType() == 2) {
|
||||
picId = row.getRowNum() + "_" + i;
|
||||
saveImage(object, picId, excelParams, titleString, pictures, params);
|
||||
} else {
|
||||
saveFieldValue(params, object, cell, excelParams, titleString, row);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (ExcelCollectionParams param : excelCollection) {
|
||||
addListContinue(object, param, row, titlemap, targetId, pictures, params);
|
||||
}
|
||||
collection.add(object);
|
||||
} catch (ExcelImportException e) {
|
||||
if (!e.getType().equals(ExcelImportEnum.VERIFY_ERROR)) {
|
||||
throw new ExcelImportException(e.getType(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取表格字段列名对应信息
|
||||
*
|
||||
* @param rows
|
||||
* @param params
|
||||
* @param excelCollection
|
||||
* @return
|
||||
*/
|
||||
private Map<Integer, String> getTitleMap(Sheet sheet, Iterator<Row> rows, ImportParams params, List<ExcelCollectionParams> excelCollection) {
|
||||
Map<Integer, String> titlemap = new HashMap<Integer, String>();
|
||||
Iterator<Cell> cellTitle = null;
|
||||
String collectionName = null;
|
||||
ExcelCollectionParams collectionParams = null;
|
||||
Row headRow = null;
|
||||
int headBegin = params.getTitleRows();
|
||||
//找到首行表头,每个sheet都必须至少有一行表头
|
||||
while(headRow == null){
|
||||
headRow = sheet.getRow(headBegin++);
|
||||
}
|
||||
//设置表头行数
|
||||
if (ExcelUtil.isMergedRegion(sheet, headRow.getRowNum(), 0)) {
|
||||
params.setHeadRows(2);
|
||||
}else{
|
||||
params.setHeadRows(1);
|
||||
}
|
||||
cellTitle = headRow.cellIterator();
|
||||
while (cellTitle.hasNext()) {
|
||||
Cell cell = cellTitle.next();
|
||||
String value = getKeyValue(cell);
|
||||
if (StringUtils.isNotEmpty(value)) {
|
||||
titlemap.put(cell.getColumnIndex(), value);//加入表头列表
|
||||
}
|
||||
}
|
||||
|
||||
//多行表头
|
||||
for (int j = headBegin; j < headBegin + params.getHeadRows()-1; j++) {
|
||||
headRow = sheet.getRow(j);
|
||||
cellTitle = headRow.cellIterator();
|
||||
while (cellTitle.hasNext()) {
|
||||
Cell cell = cellTitle.next();
|
||||
String value = getKeyValue(cell);
|
||||
if (StringUtils.isNotEmpty(value)) {
|
||||
int columnIndex = cell.getColumnIndex();
|
||||
//当前cell的上一行是否为合并单元格
|
||||
if(ExcelUtil.isMergedRegion(sheet, cell.getRowIndex()-1, columnIndex)){
|
||||
collectionName = ExcelUtil.getMergedRegionValue(sheet, cell.getRowIndex()-1, columnIndex);
|
||||
titlemap.put(cell.getColumnIndex(), collectionName + "_" + value);
|
||||
}else{
|
||||
titlemap.put(cell.getColumnIndex(), value);
|
||||
}
|
||||
/*int i = cell.getColumnIndex();
|
||||
// 用以支持重名导入
|
||||
if (titlemap.containsKey(i)) {
|
||||
collectionName = titlemap.get(i);
|
||||
collectionParams = getCollectionParams(excelCollection, collectionName);
|
||||
titlemap.put(i, collectionName + "_" + value);
|
||||
} else if (StringUtils.isNotEmpty(collectionName) && collectionParams.getExcelParams().containsKey(collectionName + "_" + value)) {
|
||||
titlemap.put(i, collectionName + "_" + value);
|
||||
} else {
|
||||
collectionName = null;
|
||||
collectionParams = null;
|
||||
}
|
||||
if (StringUtils.isEmpty(collectionName)) {
|
||||
titlemap.put(i, value);
|
||||
}*/
|
||||
}
|
||||
}
|
||||
}
|
||||
return titlemap;
|
||||
}
|
||||
/**
|
||||
* 获取这个名称对应的集合信息
|
||||
*
|
||||
* @param excelCollection
|
||||
* @param collectionName
|
||||
* @return
|
||||
*/
|
||||
private ExcelCollectionParams getCollectionParams(List<ExcelCollectionParams> excelCollection, String collectionName) {
|
||||
for (ExcelCollectionParams excelCollectionParams : excelCollection) {
|
||||
if (collectionName.equals(excelCollectionParams.getExcelName())) {
|
||||
return excelCollectionParams;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Excel 导入 field 字段类型 Integer,Long,Double,Date,String,Boolean
|
||||
*
|
||||
* @param inputstream
|
||||
* @param pojoClass
|
||||
* @param params
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public ExcelImportResult importExcelByIs(InputStream inputstream, Class<?> pojoClass, ImportParams params) throws Exception {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Excel import start ,class is {}", pojoClass);
|
||||
}
|
||||
List<T> result = new ArrayList<T>();
|
||||
Workbook book = null;
|
||||
boolean isXSSFWorkbook = true;
|
||||
if (!(inputstream.markSupported())) {
|
||||
inputstream = new PushbackInputStream(inputstream, 8);
|
||||
}
|
||||
if (POIFSFileSystem.hasPOIFSHeader(inputstream)) {
|
||||
book = new HSSFWorkbook(inputstream);
|
||||
isXSSFWorkbook = false;
|
||||
} else if (POIXMLDocument.hasOOXMLHeader(inputstream)) {
|
||||
book = new XSSFWorkbook(OPCPackage.open(inputstream));
|
||||
}
|
||||
createErrorCellStyle(book);
|
||||
Map<String, PictureData> pictures;
|
||||
for (int i = 0; i < params.getSheetNum(); i++) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug(" start to read excel by is ,startTime is {}", new Date().getTime());
|
||||
}
|
||||
if (isXSSFWorkbook) {
|
||||
pictures = PoiPublicUtil.getSheetPictrues07((XSSFSheet) book.getSheetAt(i), (XSSFWorkbook) book);
|
||||
} else {
|
||||
pictures = PoiPublicUtil.getSheetPictrues03((HSSFSheet) book.getSheetAt(i), (HSSFWorkbook) book);
|
||||
}
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug(" end to read excel by is ,endTime is {}", new Date().getTime());
|
||||
}
|
||||
result.addAll(importExcel(result, book.getSheetAt(i), pojoClass, params, pictures));
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug(" end to read excel list by pos ,endTime is {}", new Date().getTime());
|
||||
}
|
||||
}
|
||||
if (params.isNeedSave()) {
|
||||
saveThisExcel(params, pojoClass, isXSSFWorkbook, book);
|
||||
}
|
||||
return new ExcelImportResult(result, verfiyFail, book);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存字段值(获取值,校验值,追加错误信息)
|
||||
*
|
||||
* @param params
|
||||
* @param object
|
||||
* @param cell
|
||||
* @param excelParams
|
||||
* @param titleString
|
||||
* @param row
|
||||
* @throws Exception
|
||||
*/
|
||||
private void saveFieldValue(ImportParams params, Object object, Cell cell, Map<String, ExcelImportEntity> excelParams, String titleString, Row row) throws Exception {
|
||||
Object value = cellValueServer.getValue(params.getDataHanlder(), object, cell, excelParams, titleString);
|
||||
if (object instanceof Map) {
|
||||
if (params.getDataHanlder() != null) {
|
||||
params.getDataHanlder().setMapValue((Map) object, titleString, value);
|
||||
} else {
|
||||
((Map) object).put(titleString, value);
|
||||
}
|
||||
} else {
|
||||
ExcelVerifyHanlderResult verifyResult = verifyHandlerServer.verifyData(object, value, titleString, excelParams.get(titleString).getVerify(), params.getVerifyHanlder());
|
||||
if (verifyResult.isSuccess()) {
|
||||
setValues(excelParams.get(titleString), object, value);
|
||||
} else {
|
||||
Cell errorCell = row.createCell(row.getLastCellNum());
|
||||
errorCell.setCellValue(verifyResult.getMsg());
|
||||
errorCell.setCellStyle(errorCellStyle);
|
||||
verfiyFail = true;
|
||||
throw new ExcelImportException(ExcelImportEnum.VERIFY_ERROR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param object
|
||||
* @param picId
|
||||
* @param excelParams
|
||||
* @param titleString
|
||||
* @param pictures
|
||||
* @param params
|
||||
* @throws Exception
|
||||
*/
|
||||
private void saveImage(Object object, String picId, Map<String, ExcelImportEntity> excelParams, String titleString, Map<String, PictureData> pictures, ImportParams params) throws Exception {
|
||||
if (pictures == null) {
|
||||
return;
|
||||
}
|
||||
PictureData image = pictures.get(picId);
|
||||
byte[] data = image.getData();
|
||||
String fileName = "pic" + Math.round(Math.random() * 100000000000L);
|
||||
fileName += "." + PoiPublicUtil.getFileExtendName(data);
|
||||
if (excelParams.get(titleString).getSaveType() == 1) {
|
||||
String path = PoiPublicUtil.getWebRootPath(getSaveUrl(excelParams.get(titleString), object));
|
||||
File savefile = new File(path);
|
||||
if (!savefile.exists()) {
|
||||
savefile.mkdirs();
|
||||
}
|
||||
savefile = new File(path + "/" + fileName);
|
||||
FileOutputStream fos = new FileOutputStream(savefile);
|
||||
fos.write(data);
|
||||
fos.close();
|
||||
setValues(excelParams.get(titleString), object, getSaveUrl(excelParams.get(titleString), object) + "/" + fileName);
|
||||
} else {
|
||||
setValues(excelParams.get(titleString), object, data);
|
||||
}
|
||||
}
|
||||
|
||||
private void createErrorCellStyle(Workbook workbook) {
|
||||
errorCellStyle = workbook.createCellStyle();
|
||||
Font font = workbook.createFont();
|
||||
font.setColor(Font.COLOR_RED);
|
||||
errorCellStyle.setFont(font);
|
||||
}
|
||||
|
||||
}
|
||||
+282
@@ -0,0 +1,282 @@
|
||||
package com.pig4cloud.pigx.common.poi.excel.imports.base;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.baomidou.mybatisplus.core.toolkit.StringPool;
|
||||
import com.pig4cloud.pigx.common.core.util.ApplicationContextUtil;
|
||||
import com.pig4cloud.pigx.common.dict.service.AutoPoiDictServiceI;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.poi.ss.usermodel.Workbook;
|
||||
import com.pig4cloud.pigx.common.poi.excel.annotation.Excel;
|
||||
import com.pig4cloud.pigx.common.poi.excel.annotation.ExcelCollection;
|
||||
import com.pig4cloud.pigx.common.poi.excel.annotation.ExcelVerify;
|
||||
import com.pig4cloud.pigx.common.poi.excel.entity.ImportParams;
|
||||
import com.pig4cloud.pigx.common.poi.excel.entity.params.ExcelCollectionParams;
|
||||
import com.pig4cloud.pigx.common.poi.excel.entity.params.ExcelImportEntity;
|
||||
import com.pig4cloud.pigx.common.poi.excel.entity.params.ExcelVerifyEntity;
|
||||
import com.pig4cloud.pigx.common.poi.util.PoiPublicUtil;
|
||||
|
||||
/**
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
* 导入基础和,普通方法和Sax共用
|
||||
*/
|
||||
public class ImportBaseService {
|
||||
|
||||
/**
|
||||
* 把这个注解解析放到类型对象中
|
||||
*
|
||||
* @param targetId
|
||||
* @param field
|
||||
* @param excelEntity
|
||||
* @param pojoClass
|
||||
* @param getMethods
|
||||
* @param temp
|
||||
* @throws Exception
|
||||
*/
|
||||
public void addEntityToMap(String targetId, Field field, ExcelImportEntity excelEntity, Class<?> pojoClass, List<Method> getMethods, Map<String, ExcelImportEntity> temp) throws Exception {
|
||||
Excel excel = field.getAnnotation(Excel.class);
|
||||
excelEntity = new ExcelImportEntity();
|
||||
excelEntity.setType(excel.type());
|
||||
excelEntity.setSaveUrl(excel.savePath());
|
||||
excelEntity.setSaveType(excel.imageType());
|
||||
excelEntity.setReplace(excel.replace());
|
||||
excelEntity.setDatabaseFormat(excel.databaseFormat());
|
||||
excelEntity.setVerify(getImportVerify(field));
|
||||
excelEntity.setSuffix(excel.suffix());
|
||||
excelEntity.setMultiReplace(excel.multiReplace());
|
||||
if(StringUtils.isNotEmpty(excel.dicCode())){
|
||||
AutoPoiDictServiceI bossDictService = null;
|
||||
try {
|
||||
bossDictService = ApplicationContextUtil.getContext().getBean(AutoPoiDictServiceI.class);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
if(bossDictService!=null){
|
||||
String[] dictReplace = bossDictService.queryDict(excel.dictTable(), excel.dicCode(), excel.dicText());
|
||||
if(excelEntity.getReplace()!=null && dictReplace!=null && dictReplace.length!=0){
|
||||
excelEntity.setReplace(dictReplace);
|
||||
}
|
||||
}
|
||||
}
|
||||
getExcelField(targetId, field, excelEntity, excel, pojoClass);
|
||||
if (getMethods != null) {
|
||||
List<Method> newMethods = new ArrayList<Method>();
|
||||
newMethods.addAll(getMethods);
|
||||
newMethods.add(excelEntity.getMethod());
|
||||
excelEntity.setMethods(newMethods);
|
||||
}
|
||||
temp.put(excelEntity.getName(), excelEntity);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取导入校验参数
|
||||
*
|
||||
* @param field
|
||||
* @return
|
||||
*/
|
||||
public ExcelVerifyEntity getImportVerify(Field field) {
|
||||
ExcelVerify verify = field.getAnnotation(ExcelVerify.class);
|
||||
if (verify != null) {
|
||||
ExcelVerifyEntity entity = new ExcelVerifyEntity();
|
||||
entity.setEmail(verify.isEmail());
|
||||
entity.setInterHandler(verify.interHandler());
|
||||
entity.setMaxLength(verify.maxLength());
|
||||
entity.setMinLength(verify.minLength());
|
||||
entity.setMobile(verify.isMobile());
|
||||
entity.setNotNull(verify.notNull());
|
||||
entity.setRegex(verify.regex());
|
||||
entity.setRegexTip(verify.regexTip());
|
||||
entity.setTel(verify.isTel());
|
||||
return entity;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取需要导出的全部字段
|
||||
*
|
||||
*
|
||||
* @param exclusions
|
||||
* @param targetId
|
||||
* 目标ID
|
||||
* @param fields
|
||||
* @param excelCollection
|
||||
* @throws Exception
|
||||
*/
|
||||
public void getAllExcelField(String targetId, Field[] fields, Map<String, ExcelImportEntity> excelParams, List<ExcelCollectionParams> excelCollection, Class<?> pojoClass, List<Method> getMethods) throws Exception {
|
||||
ExcelImportEntity excelEntity = null;
|
||||
for (int i = 0; i < fields.length; i++) {
|
||||
Field field = fields[i];
|
||||
if (PoiPublicUtil.isNotUserExcelUserThis(null, field, targetId)) {
|
||||
continue;
|
||||
}
|
||||
if (PoiPublicUtil.isCollection(field.getType())) {
|
||||
// 集合对象设置属性
|
||||
ExcelCollectionParams collection = new ExcelCollectionParams();
|
||||
collection.setName(field.getName());
|
||||
Map<String, ExcelImportEntity> temp = new HashMap<String, ExcelImportEntity>();
|
||||
ParameterizedType pt = (ParameterizedType) field.getGenericType();
|
||||
Class<?> clz = (Class<?>) pt.getActualTypeArguments()[0];
|
||||
collection.setType(clz);
|
||||
getExcelFieldList(targetId, PoiPublicUtil.getClassFields(clz), clz, temp, null);
|
||||
collection.setExcelParams(temp);
|
||||
collection.setExcelName(field.getAnnotation(ExcelCollection.class).name());
|
||||
additionalCollectionName(collection);
|
||||
excelCollection.add(collection);
|
||||
} else if (PoiPublicUtil.isJavaClass(field)) {
|
||||
addEntityToMap(targetId, field, excelEntity, pojoClass, getMethods, excelParams);
|
||||
} else {
|
||||
List<Method> newMethods = new ArrayList<Method>();
|
||||
if (getMethods != null) {
|
||||
newMethods.addAll(getMethods);
|
||||
}
|
||||
newMethods.add(PoiPublicUtil.getMethod(field.getName(), pojoClass));
|
||||
getAllExcelField(targetId, PoiPublicUtil.getClassFields(field.getType()), excelParams, excelCollection, field.getType(), newMethods);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 追加集合名称到前面
|
||||
*
|
||||
* @param collection
|
||||
*/
|
||||
private void additionalCollectionName(ExcelCollectionParams collection) {
|
||||
Set<String> keys = new HashSet<String>();
|
||||
keys.addAll(collection.getExcelParams().keySet());
|
||||
for (String key : keys) {
|
||||
collection.getExcelParams().put(collection.getExcelName() + "_" + key, collection.getExcelParams().get(key));
|
||||
collection.getExcelParams().remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
public void getExcelField(String targetId, Field field, ExcelImportEntity excelEntity, Excel excel, Class<?> pojoClass) throws Exception {
|
||||
excelEntity.setName(getExcelName(excel.name(), targetId));
|
||||
String fieldname = field.getName();
|
||||
excelEntity.setMethod(PoiPublicUtil.getMethod(fieldname, pojoClass, field.getType(),excel.importConvert()));
|
||||
if (StringUtils.isNotEmpty(excel.importFormat())) {
|
||||
excelEntity.setFormat(excel.importFormat());
|
||||
} else {
|
||||
excelEntity.setFormat(excel.format());
|
||||
}
|
||||
}
|
||||
|
||||
public void getExcelFieldList(String targetId, Field[] fields, Class<?> pojoClass, Map<String, ExcelImportEntity> temp, List<Method> getMethods) throws Exception {
|
||||
ExcelImportEntity excelEntity = null;
|
||||
for (int i = 0; i < fields.length; i++) {
|
||||
Field field = fields[i];
|
||||
if (PoiPublicUtil.isNotUserExcelUserThis(null, field, targetId)) {
|
||||
continue;
|
||||
}
|
||||
if (PoiPublicUtil.isJavaClass(field)) {
|
||||
addEntityToMap(targetId, field, excelEntity, pojoClass, getMethods, temp);
|
||||
} else {
|
||||
List<Method> newMethods = new ArrayList<Method>();
|
||||
if (getMethods != null) {
|
||||
newMethods.addAll(getMethods);
|
||||
}
|
||||
newMethods.add(PoiPublicUtil.getMethod(field.getName(), pojoClass, field.getType()));
|
||||
getExcelFieldList(targetId, PoiPublicUtil.getClassFields(field.getType()), field.getType(), temp, newMethods);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断在这个单元格显示的名称
|
||||
*
|
||||
* @param exportName
|
||||
* @param targetId
|
||||
* @return
|
||||
*/
|
||||
public String getExcelName(String exportName, String targetId) {
|
||||
if (exportName.indexOf("_") < 0) {
|
||||
return exportName;
|
||||
}
|
||||
String[] arr = exportName.split(StringPool.COMMA);
|
||||
for (String str : arr) {
|
||||
if (str.indexOf(targetId) != -1) {
|
||||
return str.split("_")[0];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Object getFieldBySomeMethod(List<Method> list, Object t) throws Exception {
|
||||
Method m;
|
||||
for (int i = 0; i < list.size() - 1; i++) {
|
||||
m = list.get(i);
|
||||
t = m.invoke(t, new Object[] {});
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
public void saveThisExcel(ImportParams params, Class<?> pojoClass, boolean isXSSFWorkbook, Workbook book) throws Exception {
|
||||
String path = PoiPublicUtil.getWebRootPath(getSaveExcelUrl(params, pojoClass));
|
||||
File savefile = new File(path);
|
||||
if (!savefile.exists()) {
|
||||
savefile.mkdirs();
|
||||
}
|
||||
SimpleDateFormat format = new SimpleDateFormat("yyyMMddHHmmss");
|
||||
FileOutputStream fos = new FileOutputStream(path + "/" + format.format(new Date()) + "_" + Math.round(Math.random() * 100000) + (isXSSFWorkbook == true ? ".xlsx" : ".xls"));
|
||||
book.write(fos);
|
||||
fos.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取保存的Excel 的真实路径
|
||||
*
|
||||
* @param params
|
||||
* @param pojoClass
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public String getSaveExcelUrl(ImportParams params, Class<?> pojoClass) throws Exception {
|
||||
String url = "";
|
||||
if (params.getSaveUrl().equals("upload/excelUpload")) {
|
||||
url = pojoClass.getName().split("\\.")[pojoClass.getName().split("\\.").length - 1];
|
||||
return params.getSaveUrl() + "/" + url;
|
||||
}
|
||||
return params.getSaveUrl();
|
||||
}
|
||||
|
||||
/**
|
||||
* 多个get 最后再set
|
||||
*
|
||||
* @param setMethods
|
||||
* @param object
|
||||
*/
|
||||
public void setFieldBySomeMethod(List<Method> setMethods, Object object, Object value) throws Exception {
|
||||
Object t = getFieldBySomeMethod(setMethods, object);
|
||||
setMethods.get(setMethods.size() - 1).invoke(t, value);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param entity
|
||||
* @param object
|
||||
* @param value
|
||||
* @throws Exception
|
||||
*/
|
||||
public void setValues(ExcelImportEntity entity, Object object, Object value) throws Exception {
|
||||
if (entity.getMethods() != null) {
|
||||
setFieldBySomeMethod(entity.getMethods(), object, value);
|
||||
} else {
|
||||
entity.getMethod().invoke(object, value);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
/**
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
* 导入类
|
||||
*/
|
||||
package com.pig4cloud.pigx.common.poi.excel.imports;
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
package com.pig4cloud.pigx.common.poi.excel.imports.sax;
|
||||
|
||||
import com.pig4cloud.pigx.common.poi.excel.entity.ImportParams;
|
||||
import com.pig4cloud.pigx.common.poi.excel.imports.sax.parse.ISaxRowRead;
|
||||
import com.pig4cloud.pigx.common.poi.excel.imports.sax.parse.SaxRowRead;
|
||||
import com.pig4cloud.pigx.common.poi.exception.excel.ExcelImportException;
|
||||
import com.pig4cloud.pigx.common.poi.handler.inter.IExcelReadRowHanlder;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.poi.openxml4j.opc.OPCPackage;
|
||||
import org.apache.poi.xssf.eventusermodel.XSSFReader;
|
||||
import org.apache.poi.xssf.model.SharedStringsTable;
|
||||
import org.xml.sax.ContentHandler;
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.XMLReader;
|
||||
import org.xml.sax.helpers.XMLReaderFactory;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
* 基于SAX Excel大数据读取,读取Excel 07版本,不支持图片读取
|
||||
*/
|
||||
@Slf4j
|
||||
@SuppressWarnings("rawtypes")
|
||||
public class SaxReadExcel {
|
||||
|
||||
|
||||
public <T> List<T> readExcel(InputStream inputstream, Class<?> pojoClass, ImportParams params, ISaxRowRead rowRead, IExcelReadRowHanlder hanlder) {
|
||||
try {
|
||||
OPCPackage opcPackage = OPCPackage.open(inputstream);
|
||||
return readExcel(opcPackage, pojoClass, params, rowRead, hanlder);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
throw new ExcelImportException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private <T> List<T> readExcel(OPCPackage opcPackage, Class<?> pojoClass, ImportParams params, ISaxRowRead rowRead, IExcelReadRowHanlder hanlder) {
|
||||
try {
|
||||
XSSFReader xssfReader = new XSSFReader(opcPackage);
|
||||
SharedStringsTable sst = xssfReader.getSharedStringsTable();
|
||||
if (rowRead == null) {
|
||||
rowRead = new SaxRowRead(pojoClass, params, hanlder);
|
||||
}
|
||||
XMLReader parser = fetchSheetParser(sst, rowRead);
|
||||
Iterator<InputStream> sheets = xssfReader.getSheetsData();
|
||||
int sheetIndex = 0;
|
||||
while (sheets.hasNext() && sheetIndex < params.getSheetNum()) {
|
||||
sheetIndex++;
|
||||
InputStream sheet = sheets.next();
|
||||
InputSource sheetSource = new InputSource(sheet);
|
||||
parser.parse(sheetSource);
|
||||
sheet.close();
|
||||
}
|
||||
return rowRead.getList();
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
throw new ExcelImportException("SAX导入数据失败");
|
||||
}
|
||||
}
|
||||
|
||||
private XMLReader fetchSheetParser(SharedStringsTable sst, ISaxRowRead rowRead) throws SAXException {
|
||||
XMLReader parser = XMLReaderFactory.createXMLReader("org.apache.xerces.parsers.SAXParser");
|
||||
ContentHandler handler = new SheetHandler(sst, rowRead);
|
||||
parser.setContentHandler(handler);
|
||||
return parser;
|
||||
}
|
||||
|
||||
}
|
||||
+122
@@ -0,0 +1,122 @@
|
||||
package com.pig4cloud.pigx.common.poi.excel.imports.sax;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
|
||||
import org.apache.poi.xssf.model.SharedStringsTable;
|
||||
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
|
||||
import com.pig4cloud.pigx.common.poi.excel.entity.enmus.CellValueType;
|
||||
import com.pig4cloud.pigx.common.poi.excel.entity.sax.SaxReadCellEntity;
|
||||
import com.pig4cloud.pigx.common.poi.excel.imports.sax.parse.ISaxRowRead;
|
||||
import org.xml.sax.Attributes;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.helpers.DefaultHandler;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
* 回调接口
|
||||
*/
|
||||
public class SheetHandler extends DefaultHandler {
|
||||
|
||||
private SharedStringsTable sst;
|
||||
private String lastContents;
|
||||
|
||||
// 当前行
|
||||
private int curRow = 0;
|
||||
// 当前列
|
||||
private int curCol = 0;
|
||||
|
||||
private CellValueType type;
|
||||
|
||||
private ISaxRowRead read;
|
||||
|
||||
// 存储行记录的容器
|
||||
private List<SaxReadCellEntity> rowlist = Lists.newArrayList();
|
||||
|
||||
public SheetHandler(SharedStringsTable sst, ISaxRowRead rowRead) {
|
||||
this.sst = sst;
|
||||
this.read = rowRead;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException {
|
||||
// 置空
|
||||
lastContents = "";
|
||||
// c => 单元格
|
||||
if ("c".equals(name)) {
|
||||
// 如果下一个元素是 SST 的索引,则将nextIsString标记为true
|
||||
String cellType = attributes.getValue("t");
|
||||
if ("s".equals(cellType)) {
|
||||
type = CellValueType.String;
|
||||
return;
|
||||
}
|
||||
// 日期格式
|
||||
cellType = attributes.getValue("s");
|
||||
if ("1".equals(cellType)) {
|
||||
type = CellValueType.Date;
|
||||
} else if ("2".equals(cellType)) {
|
||||
type = CellValueType.Number;
|
||||
}
|
||||
} else if ("t".equals(name)) {// 当元素为t时
|
||||
type = CellValueType.TElement;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endElement(String uri, String localName, String name) throws SAXException {
|
||||
|
||||
// 根据SST的索引值的到单元格的真正要存储的字符串
|
||||
// 这时characters()方法可能会被调用多次
|
||||
if (CellValueType.String.equals(type)) {
|
||||
try {
|
||||
int idx = Integer.parseInt(lastContents);
|
||||
lastContents = new XSSFRichTextString(sst.getEntryAt(idx)).toString();
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
}
|
||||
// t元素也包含字符串
|
||||
if (CellValueType.TElement.equals(type)) {
|
||||
String value = lastContents.trim();
|
||||
rowlist.add(curCol, new SaxReadCellEntity(CellValueType.String, value));
|
||||
curCol++;
|
||||
type = CellValueType.None;
|
||||
// v => 单元格的值,如果单元格是字符串则v标签的值为该字符串在SST中的索引
|
||||
// 将单元格内容加入rowlist中,在这之前先去掉字符串前后的空白符
|
||||
} else if ("v".equals(name)) {
|
||||
String value = lastContents.trim();
|
||||
value = value.equals("") ? " " : value;
|
||||
if (CellValueType.Date.equals(type)) {
|
||||
Date date = HSSFDateUtil.getJavaDate(Double.valueOf(value));
|
||||
rowlist.add(curCol, new SaxReadCellEntity(CellValueType.Date, date));
|
||||
} else if (CellValueType.Number.equals(type)) {
|
||||
BigDecimal bd = new BigDecimal(value);
|
||||
rowlist.add(curCol, new SaxReadCellEntity(CellValueType.Number, bd));
|
||||
} else if (CellValueType.String.equals(type)) {
|
||||
rowlist.add(curCol, new SaxReadCellEntity(CellValueType.String, value));
|
||||
}
|
||||
curCol++;
|
||||
} else if (name.equals("row")) {// 如果标签名称为 row ,这说明已到行尾,调用 optRows() 方法
|
||||
read.parse(curRow, rowlist);
|
||||
rowlist.clear();
|
||||
curRow++;
|
||||
curCol = 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void characters(char[] ch, int start, int length) throws SAXException {
|
||||
// 得到单元格内容的值
|
||||
lastContents += new String(ch, start, length);
|
||||
}
|
||||
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
package com.pig4cloud.pigx.common.poi.excel.imports.sax.parse;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.pig4cloud.pigx.common.poi.excel.entity.sax.SaxReadCellEntity;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
*/
|
||||
public interface ISaxRowRead {
|
||||
/**
|
||||
* 获取返回数据
|
||||
*
|
||||
* @param <T>
|
||||
* @return
|
||||
*/
|
||||
public <T> List<T> getList();
|
||||
|
||||
/**
|
||||
* 解析数据
|
||||
*
|
||||
* @param index
|
||||
* @param datas
|
||||
*/
|
||||
public void parse(int index, List<SaxReadCellEntity> datas);
|
||||
|
||||
}
|
||||
+192
@@ -0,0 +1,192 @@
|
||||
package com.pig4cloud.pigx.common.poi.excel.imports.sax.parse;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.pig4cloud.pigx.common.poi.excel.annotation.ExcelTarget;
|
||||
import com.pig4cloud.pigx.common.poi.excel.entity.ImportParams;
|
||||
import com.pig4cloud.pigx.common.poi.excel.entity.params.ExcelCollectionParams;
|
||||
import com.pig4cloud.pigx.common.poi.excel.entity.params.ExcelImportEntity;
|
||||
import com.pig4cloud.pigx.common.poi.excel.entity.sax.SaxReadCellEntity;
|
||||
import com.pig4cloud.pigx.common.poi.excel.imports.CellValueServer;
|
||||
import com.pig4cloud.pigx.common.poi.excel.imports.base.ImportBaseService;
|
||||
import com.pig4cloud.pigx.common.poi.exception.excel.ExcelImportException;
|
||||
import com.pig4cloud.pigx.common.poi.handler.inter.IExcelReadRowHanlder;
|
||||
import com.pig4cloud.pigx.common.poi.util.PoiPublicUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
* 当行读取数据
|
||||
*/
|
||||
@Slf4j
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
public class SaxRowRead extends ImportBaseService implements ISaxRowRead {
|
||||
|
||||
/** 需要返回的数据 **/
|
||||
private List list;
|
||||
/** 导出的对象 **/
|
||||
private Class<?> pojoClass;
|
||||
/** 导入参数 **/
|
||||
private ImportParams params;
|
||||
/** 列表头对应关系 **/
|
||||
private Map<Integer, String> titlemap = new HashMap<Integer, String>();
|
||||
/** 当前的对象 **/
|
||||
private Object object = null;
|
||||
|
||||
private Map<String, ExcelImportEntity> excelParams = new HashMap<String, ExcelImportEntity>();
|
||||
|
||||
private List<ExcelCollectionParams> excelCollection = new ArrayList<ExcelCollectionParams>();
|
||||
|
||||
private String targetId;
|
||||
|
||||
private CellValueServer cellValueServer;
|
||||
|
||||
private IExcelReadRowHanlder hanlder;
|
||||
|
||||
public SaxRowRead(Class<?> pojoClass, ImportParams params, IExcelReadRowHanlder hanlder) {
|
||||
list = Lists.newArrayList();
|
||||
this.params = params;
|
||||
this.pojoClass = pojoClass;
|
||||
cellValueServer = new CellValueServer();
|
||||
this.hanlder = hanlder;
|
||||
initParams(pojoClass, params);
|
||||
}
|
||||
|
||||
private void initParams(Class<?> pojoClass, ImportParams params) {
|
||||
try {
|
||||
|
||||
Field fileds[] = PoiPublicUtil.getClassFields(pojoClass);
|
||||
ExcelTarget etarget = pojoClass.getAnnotation(ExcelTarget.class);
|
||||
if (etarget != null) {
|
||||
targetId = etarget.value();
|
||||
}
|
||||
getAllExcelField(targetId, fileds, excelParams, excelCollection, pojoClass, null);
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
throw new ExcelImportException(e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> List<T> getList() {
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void parse(int index, List<SaxReadCellEntity> datas) {
|
||||
try {
|
||||
if (datas == null || datas.size() == 0) {
|
||||
return;
|
||||
}
|
||||
// 标题行跳过
|
||||
if (index < params.getTitleRows()) {
|
||||
return;
|
||||
}
|
||||
// 表头行
|
||||
if (index < params.getTitleRows() + params.getHeadRows()) {
|
||||
addHeadData(datas);
|
||||
} else {
|
||||
addListData(datas);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
throw new ExcelImportException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 集合元素处理
|
||||
*
|
||||
* @param datas
|
||||
*/
|
||||
private void addListData(List<SaxReadCellEntity> datas) throws Exception {
|
||||
// 判断是集合元素还是不是集合元素,如果是就继续加入这个集合,不是就创建新的对象
|
||||
if ((datas.get(params.getKeyIndex()) == null || StringUtils.isEmpty(String.valueOf(datas.get(params.getKeyIndex()).getValue()))) && object != null) {
|
||||
for (ExcelCollectionParams param : excelCollection) {
|
||||
addListContinue(object, param, datas, titlemap, targetId, params);
|
||||
}
|
||||
} else {
|
||||
if (object != null && hanlder != null) {
|
||||
hanlder.hanlder(object);
|
||||
}
|
||||
object = PoiPublicUtil.createObject(pojoClass, targetId);
|
||||
SaxReadCellEntity entity;
|
||||
for (int i = 0, le = datas.size(); i < le; i++) {
|
||||
entity = datas.get(i);
|
||||
String titleString = (String) titlemap.get(i);
|
||||
if (excelParams.containsKey(titleString)) {
|
||||
saveFieldValue(params, object, entity, excelParams, titleString);
|
||||
}
|
||||
}
|
||||
for (ExcelCollectionParams param : excelCollection) {
|
||||
addListContinue(object, param, datas, titlemap, targetId, params);
|
||||
}
|
||||
if (hanlder == null) {
|
||||
list.add(object);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/***
|
||||
* 向List里面继续添加元素
|
||||
*
|
||||
* @param exclusions
|
||||
* @param object
|
||||
* @param param
|
||||
* @param datas
|
||||
* @param titlemap
|
||||
* @param targetId
|
||||
* @param params
|
||||
*/
|
||||
private void addListContinue(Object object, ExcelCollectionParams param, List<SaxReadCellEntity> datas, Map<Integer, String> titlemap, String targetId, ImportParams params) throws Exception {
|
||||
Collection collection = (Collection) PoiPublicUtil.getMethod(param.getName(), object.getClass()).invoke(object, new Object[] {});
|
||||
Object entity = PoiPublicUtil.createObject(param.getType(), targetId);
|
||||
boolean isUsed = false;// 是否需要加上这个对象
|
||||
for (int i = 0; i < datas.size(); i++) {
|
||||
String titleString = (String) titlemap.get(i);
|
||||
if (param.getExcelParams().containsKey(titleString)) {
|
||||
saveFieldValue(params, entity, datas.get(i), param.getExcelParams(), titleString);
|
||||
isUsed = true;
|
||||
}
|
||||
}
|
||||
if (isUsed) {
|
||||
collection.add(entity);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置值
|
||||
*
|
||||
* @param params
|
||||
* @param object
|
||||
* @param entity
|
||||
* @param excelParams
|
||||
* @param titleString
|
||||
* @throws Exception
|
||||
*/
|
||||
private void saveFieldValue(ImportParams params, Object object, SaxReadCellEntity entity, Map<String, ExcelImportEntity> excelParams, String titleString) throws Exception {
|
||||
Object value = cellValueServer.getValue(params.getDataHanlder(), object, entity, excelParams, titleString);
|
||||
setValues(excelParams.get(titleString), object, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* put 表头数据
|
||||
*
|
||||
* @param datas
|
||||
*/
|
||||
private void addHeadData(List<SaxReadCellEntity> datas) {
|
||||
for (int i = 0; i < datas.size(); i++) {
|
||||
if (StringUtils.isNotEmpty(String.valueOf(datas.get(i).getValue()))) {
|
||||
titlemap.put(i, String.valueOf(datas.get(i).getValue()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+131
@@ -0,0 +1,131 @@
|
||||
package com.pig4cloud.pigx.common.poi.excel.imports.verifys;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import com.pig4cloud.pigx.common.poi.excel.entity.result.ExcelVerifyHanlderResult;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
* 基础校验工具类
|
||||
*/
|
||||
public class BaseVerifyHandler {
|
||||
|
||||
private static String NOT_NULL = "不允许为空";
|
||||
private static String IS_MOBILE = "不是手机号";
|
||||
private static String IS_TEL = "不是电话号码";
|
||||
private static String IS_EMAIL = "不是邮箱地址";
|
||||
private static String MIN_LENGHT = "小于规定长度";
|
||||
private static String MAX_LENGHT = "超过规定长度";
|
||||
|
||||
private static Pattern mobilePattern = Pattern.compile("^[1][3,4,5,8,7][0-9]{9}$");
|
||||
|
||||
private static Pattern telPattern = Pattern.compile("^([0][1-9]{2,3}-)?[0-9]{5,10}$");
|
||||
|
||||
private static Pattern emailPattern = Pattern.compile("^([a-zA-Z0-9]+[_|\\_|\\.]?)*[a-zA-Z0-9]+@([a-zA-Z0-9]+[_|\\_|\\.]?)*[a-zA-Z0-9]+\\.[a-zA-Z]{2,3}$");
|
||||
|
||||
/**
|
||||
* email校验
|
||||
*
|
||||
* @param name
|
||||
* @param val
|
||||
* @return
|
||||
*/
|
||||
public static ExcelVerifyHanlderResult isEmail(String name, Object val) {
|
||||
if (!emailPattern.matcher(String.valueOf(val)).matches()) {
|
||||
return new ExcelVerifyHanlderResult(false, name + IS_EMAIL);
|
||||
}
|
||||
return new ExcelVerifyHanlderResult(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 手机校验
|
||||
*
|
||||
* @param name
|
||||
* @param val
|
||||
* @return
|
||||
*/
|
||||
public static ExcelVerifyHanlderResult isMobile(String name, Object val) {
|
||||
if (!mobilePattern.matcher(String.valueOf(val)).matches()) {
|
||||
return new ExcelVerifyHanlderResult(false, name + IS_MOBILE);
|
||||
}
|
||||
return new ExcelVerifyHanlderResult(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 电话校验
|
||||
*
|
||||
* @param name
|
||||
* @param val
|
||||
* @return
|
||||
*/
|
||||
public static ExcelVerifyHanlderResult isTel(String name, Object val) {
|
||||
if (!telPattern.matcher(String.valueOf(val)).matches()) {
|
||||
return new ExcelVerifyHanlderResult(false, name + IS_TEL);
|
||||
}
|
||||
return new ExcelVerifyHanlderResult(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 最大长度校验
|
||||
*
|
||||
* @param name
|
||||
* @param val
|
||||
* @return
|
||||
*/
|
||||
public static ExcelVerifyHanlderResult maxLength(String name, Object val, int maxLength) {
|
||||
if (notNull(name, val).isSuccess() && String.valueOf(val).length() > maxLength) {
|
||||
return new ExcelVerifyHanlderResult(false, name + MAX_LENGHT);
|
||||
}
|
||||
return new ExcelVerifyHanlderResult(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 最小长度校验
|
||||
*
|
||||
* @param name
|
||||
* @param val
|
||||
* @param minLength
|
||||
* @return
|
||||
*/
|
||||
public static ExcelVerifyHanlderResult minLength(String name, Object val, int minLength) {
|
||||
if (notNull(name, val).isSuccess() && String.valueOf(val).length() < minLength) {
|
||||
return new ExcelVerifyHanlderResult(false, name + MIN_LENGHT);
|
||||
}
|
||||
return new ExcelVerifyHanlderResult(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 非空校验
|
||||
*
|
||||
* @param name
|
||||
* @param val
|
||||
* @return
|
||||
*/
|
||||
public static ExcelVerifyHanlderResult notNull(String name, Object val) {
|
||||
if (val == null || val.toString().equals("")) {
|
||||
return new ExcelVerifyHanlderResult(false, name + NOT_NULL);
|
||||
}
|
||||
return new ExcelVerifyHanlderResult(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 正则表达式校验
|
||||
*
|
||||
* @param name
|
||||
* @param val
|
||||
* @param regex
|
||||
* @param regexTip
|
||||
* @return
|
||||
*/
|
||||
public static ExcelVerifyHanlderResult regex(String name, Object val, String regex, String regexTip) {
|
||||
Pattern pattern = Pattern.compile(regex);
|
||||
if (!pattern.matcher(String.valueOf(val)).matches()) {
|
||||
return new ExcelVerifyHanlderResult(false, name + regexTip);
|
||||
}
|
||||
return new ExcelVerifyHanlderResult(true);
|
||||
}
|
||||
|
||||
}
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
package com.pig4cloud.pigx.common.poi.excel.imports.verifys;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import com.pig4cloud.pigx.common.poi.excel.entity.params.ExcelVerifyEntity;
|
||||
import com.pig4cloud.pigx.common.poi.excel.entity.result.ExcelVerifyHanlderResult;
|
||||
import com.pig4cloud.pigx.common.poi.handler.inter.IExcelVerifyHandler;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
* 校验服务
|
||||
*/
|
||||
public class VerifyHandlerServer {
|
||||
|
||||
private final static ExcelVerifyHanlderResult DEFAULT_RESULT = new ExcelVerifyHanlderResult(true);
|
||||
|
||||
private void addVerifyResult(ExcelVerifyHanlderResult hanlderResult, ExcelVerifyHanlderResult result) {
|
||||
if (!hanlderResult.isSuccess()) {
|
||||
result.setSuccess(false);
|
||||
result.setMsg((StringUtils.isEmpty(result.getMsg()) ? "" : result.getMsg() + " , ") + hanlderResult.getMsg());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验数据
|
||||
*
|
||||
* @param object
|
||||
* @param value
|
||||
* @param name
|
||||
* @param verify
|
||||
* @param excelVerifyHandler
|
||||
* @return
|
||||
*/
|
||||
public ExcelVerifyHanlderResult verifyData(Object object, Object value, String name, ExcelVerifyEntity verify, IExcelVerifyHandler excelVerifyHandler) {
|
||||
if (verify == null) {
|
||||
return DEFAULT_RESULT;
|
||||
}
|
||||
ExcelVerifyHanlderResult result = new ExcelVerifyHanlderResult(true, "");
|
||||
if (verify.isNotNull()) {
|
||||
addVerifyResult(BaseVerifyHandler.notNull(name, value), result);
|
||||
}
|
||||
if (verify.isEmail()) {
|
||||
addVerifyResult(BaseVerifyHandler.isEmail(name, value), result);
|
||||
}
|
||||
if (verify.isMobile()) {
|
||||
addVerifyResult(BaseVerifyHandler.isMobile(name, value), result);
|
||||
}
|
||||
if (verify.isTel()) {
|
||||
addVerifyResult(BaseVerifyHandler.isTel(name, value), result);
|
||||
}
|
||||
if (verify.getMaxLength() != -1) {
|
||||
addVerifyResult(BaseVerifyHandler.maxLength(name, value, verify.getMaxLength()), result);
|
||||
}
|
||||
if (verify.getMinLength() != -1) {
|
||||
addVerifyResult(BaseVerifyHandler.minLength(name, value, verify.getMinLength()), result);
|
||||
}
|
||||
if (StringUtils.isNotEmpty(verify.getRegex())) {
|
||||
addVerifyResult(BaseVerifyHandler.regex(name, value, verify.getRegex(), verify.getRegexTip()), result);
|
||||
}
|
||||
if (verify.isInterHandler()) {
|
||||
addVerifyResult(excelVerifyHandler.verifyHandler(object, name, value), result);
|
||||
}
|
||||
return result;
|
||||
|
||||
}
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
package com.pig4cloud.pigx.common.poi.excel.view;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.springframework.web.servlet.view.AbstractView;
|
||||
|
||||
/**
|
||||
* 基础抽象Excel View
|
||||
*
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
*/
|
||||
public abstract class MiniAbstractExcelView extends AbstractView {
|
||||
|
||||
private static final String CONTENT_TYPE = "application/vnd.ms-excel";
|
||||
|
||||
protected static final String HSSF = ".xls";
|
||||
protected static final String XSSF = ".xlsx";
|
||||
|
||||
public MiniAbstractExcelView() {
|
||||
setContentType(CONTENT_TYPE);
|
||||
}
|
||||
|
||||
protected boolean isIE(HttpServletRequest request) {
|
||||
return (request.getHeader("USER-AGENT").toLowerCase().indexOf("msie") > 0 || request.getHeader("USER-AGENT").toLowerCase().indexOf("rv:11.0") > 0) ? true : false;
|
||||
}
|
||||
|
||||
}
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
package com.pig4cloud.pigx.common.poi.excel.view;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.ServletOutputStream;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
import org.apache.poi.ss.usermodel.Workbook;
|
||||
import com.pig4cloud.pigx.common.poi.excel.ExcelExportUtil;
|
||||
import com.pig4cloud.pigx.common.poi.excel.def.NormalExcelConstants;
|
||||
import com.pig4cloud.pigx.common.poi.excel.entity.ExportParams;
|
||||
import com.pig4cloud.pigx.common.poi.excel.export.ExcelExportServer;
|
||||
import org.springframework.stereotype.Controller;
|
||||
|
||||
/**
|
||||
* Entity 实体数据对象导出
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
*
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@Controller(NormalExcelConstants.PIGX_ENTITY_EXCEL_VIEW)
|
||||
public class PigxEntityExcelView extends MiniAbstractExcelView {
|
||||
|
||||
public PigxEntityExcelView() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
|
||||
String codedFileName = "临时文件";
|
||||
Workbook workbook = null;
|
||||
if (model.containsKey(NormalExcelConstants.MAP_LIST)) {
|
||||
List<Map<String, Object>> list = (List<Map<String, Object>>) model.get(NormalExcelConstants.MAP_LIST);
|
||||
if (list.size() == 0) {
|
||||
throw new RuntimeException("MAP_LIST IS NULL");
|
||||
}
|
||||
workbook = ExcelExportUtil.exportExcel((ExportParams) list.get(0).get(NormalExcelConstants.PARAMS), (Class<?>) list.get(0).get(NormalExcelConstants.CLASS), (Collection<?>) list.get(0).get(NormalExcelConstants.DATA_LIST));
|
||||
for (int i = 1; i < list.size(); i++) {
|
||||
new ExcelExportServer().createSheet(workbook, (ExportParams) list.get(i).get(NormalExcelConstants.PARAMS), (Class<?>) list.get(i).get(NormalExcelConstants.CLASS), (Collection<?>) list.get(i).get(NormalExcelConstants.DATA_LIST));
|
||||
}
|
||||
} else {
|
||||
workbook = ExcelExportUtil.exportExcel((ExportParams) model.get(NormalExcelConstants.PARAMS), (Class<?>) model.get(NormalExcelConstants.CLASS), (Collection<?>) model.get(NormalExcelConstants.DATA_LIST));
|
||||
}
|
||||
if (model.containsKey(NormalExcelConstants.FILE_NAME)) {
|
||||
codedFileName = (String) model.get(NormalExcelConstants.FILE_NAME);
|
||||
}
|
||||
if (workbook instanceof HSSFWorkbook) {
|
||||
codedFileName += HSSF;
|
||||
} else {
|
||||
codedFileName += XSSF;
|
||||
}
|
||||
if (isIE(request)) {
|
||||
codedFileName = java.net.URLEncoder.encode(codedFileName, "UTF8");
|
||||
} else {
|
||||
codedFileName = new String(codedFileName.getBytes("UTF-8"), "ISO-8859-1");
|
||||
}
|
||||
response.setHeader("content-disposition", "attachment;filename=" + codedFileName);
|
||||
ServletOutputStream out = response.getOutputStream();
|
||||
workbook.write(out);
|
||||
out.flush();
|
||||
}
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
package com.pig4cloud.pigx.common.poi.excel.view;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.ServletOutputStream;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
import org.apache.poi.ss.usermodel.Workbook;
|
||||
import com.pig4cloud.pigx.common.poi.excel.ExcelExportUtil;
|
||||
import com.pig4cloud.pigx.common.poi.excel.def.MapExcelConstants;
|
||||
import com.pig4cloud.pigx.common.poi.excel.entity.ExportParams;
|
||||
import com.pig4cloud.pigx.common.poi.excel.entity.params.ExcelExportEntity;
|
||||
import org.springframework.stereotype.Controller;
|
||||
|
||||
/**
|
||||
* Map 数据对象接口导出
|
||||
*
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@Controller(MapExcelConstants.PIGX_MAP_EXCEL_VIEW)
|
||||
public class PigxMapExcelView extends MiniAbstractExcelView {
|
||||
|
||||
public PigxMapExcelView() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
|
||||
String codedFileName = "临时文件";
|
||||
Workbook workbook = ExcelExportUtil.exportExcel((ExportParams) model.get(MapExcelConstants.PARAMS), (List<ExcelExportEntity>) model.get(MapExcelConstants.ENTITY_LIST), (Collection<? extends Map<?, ?>>) model.get(MapExcelConstants.MAP_LIST));
|
||||
if (model.containsKey(MapExcelConstants.FILE_NAME)) {
|
||||
codedFileName = (String) model.get(MapExcelConstants.FILE_NAME);
|
||||
}
|
||||
if (workbook instanceof HSSFWorkbook) {
|
||||
codedFileName += HSSF;
|
||||
} else {
|
||||
codedFileName += XSSF;
|
||||
}
|
||||
if (isIE(request)) {
|
||||
codedFileName = java.net.URLEncoder.encode(codedFileName, "UTF8");
|
||||
} else {
|
||||
codedFileName = new String(codedFileName.getBytes("UTF-8"), "ISO-8859-1");
|
||||
}
|
||||
response.setHeader("content-disposition", "attachment;filename=" + codedFileName);
|
||||
ServletOutputStream out = response.getOutputStream();
|
||||
workbook.write(out);
|
||||
out.flush();
|
||||
}
|
||||
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
package com.pig4cloud.pigx.common.poi.excel.view;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.ServletOutputStream;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
import org.apache.poi.ss.usermodel.Workbook;
|
||||
import com.pig4cloud.pigx.common.poi.excel.ExcelExportUtil;
|
||||
import com.pig4cloud.pigx.common.poi.excel.def.NormalExcelConstants;
|
||||
import com.pig4cloud.pigx.common.poi.excel.def.TemplateExcelConstants;
|
||||
import com.pig4cloud.pigx.common.poi.excel.entity.TemplateExportParams;
|
||||
import org.springframework.stereotype.Controller;
|
||||
|
||||
/**
|
||||
* Excel 模板导出
|
||||
*
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@Controller(TemplateExcelConstants.PIGX_TEMPLATE_EXCEL_VIEW)
|
||||
public class PigxTemplateExcelView extends MiniAbstractExcelView {
|
||||
|
||||
public PigxTemplateExcelView() {
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
|
||||
String codedFileName = "临时文件";
|
||||
Workbook workbook = ExcelExportUtil.exportExcel((TemplateExportParams) model.get(TemplateExcelConstants.PARAMS), (Class<?>) model.get(TemplateExcelConstants.CLASS), (List<?>) model.get(TemplateExcelConstants.LIST_DATA), (Map<String, Object>) model.get(TemplateExcelConstants.MAP_DATA));
|
||||
if (model.containsKey(NormalExcelConstants.FILE_NAME)) {
|
||||
codedFileName = (String) model.get(NormalExcelConstants.FILE_NAME);
|
||||
}
|
||||
if (workbook instanceof HSSFWorkbook) {
|
||||
codedFileName += HSSF;
|
||||
} else {
|
||||
codedFileName += XSSF;
|
||||
}
|
||||
if (isIE(request)) {
|
||||
codedFileName = java.net.URLEncoder.encode(codedFileName, "UTF8");
|
||||
} else {
|
||||
codedFileName = new String(codedFileName.getBytes("UTF-8"), "ISO-8859-1");
|
||||
}
|
||||
response.setHeader("content-disposition", "attachment;filename=" + codedFileName);
|
||||
ServletOutputStream out = response.getOutputStream();
|
||||
workbook.write(out);
|
||||
out.flush();
|
||||
}
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
package com.pig4cloud.pigx.common.poi.excel.view;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.ServletOutputStream;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.apache.poi.xwpf.usermodel.XWPFDocument;
|
||||
import com.pig4cloud.pigx.common.poi.excel.def.TemplateWordConstants;
|
||||
import com.pig4cloud.pigx.common.poi.word.WordExportUtil;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.servlet.view.AbstractView;
|
||||
|
||||
/**
|
||||
* Word模板导出
|
||||
*
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@Controller(TemplateWordConstants.PIGX_TEMPLATE_WORD_VIEW)
|
||||
public class PigxTemplateWordView extends AbstractView {
|
||||
|
||||
private static final String CONTENT_TYPE = "application/msword";
|
||||
|
||||
public PigxTemplateWordView() {
|
||||
setContentType(CONTENT_TYPE);
|
||||
}
|
||||
|
||||
public boolean isIE(HttpServletRequest request) {
|
||||
return (request.getHeader("USER-AGENT").toLowerCase().indexOf("msie") > 0 || request.getHeader("USER-AGENT").toLowerCase().indexOf("rv:11.0") > 0) ? true : false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
|
||||
String codedFileName = "临时文件.docx";
|
||||
if (model.containsKey(TemplateWordConstants.FILE_NAME)) {
|
||||
codedFileName = (String) model.get(TemplateWordConstants.FILE_NAME) + ".docx";
|
||||
}
|
||||
if (isIE(request)) {
|
||||
codedFileName = java.net.URLEncoder.encode(codedFileName, "UTF8");
|
||||
} else {
|
||||
codedFileName = new String(codedFileName.getBytes("UTF-8"), "ISO-8859-1");
|
||||
}
|
||||
response.setHeader("content-disposition", "attachment;filename=" + codedFileName);
|
||||
XWPFDocument document = WordExportUtil.exportWord07((String) model.get(TemplateWordConstants.URL), (Map<String, Object>) model.get(TemplateWordConstants.MAP_DATA));
|
||||
ServletOutputStream out = response.getOutputStream();
|
||||
document.write(out);
|
||||
out.flush();
|
||||
}
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
package com.pig4cloud.pigx.common.poi.exception.excel;
|
||||
|
||||
import com.pig4cloud.pigx.common.poi.exception.excel.enums.ExcelExportEnum;
|
||||
|
||||
/**
|
||||
* 导出异常
|
||||
*
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
*/
|
||||
public class ExcelExportException extends RuntimeException {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private ExcelExportEnum type;
|
||||
|
||||
public ExcelExportException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public ExcelExportException(ExcelExportEnum type) {
|
||||
super(type.getMsg());
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public ExcelExportException(ExcelExportEnum type, Throwable cause) {
|
||||
super(type.getMsg(), cause);
|
||||
}
|
||||
|
||||
public ExcelExportException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public ExcelExportException(String message, ExcelExportEnum type) {
|
||||
super(message);
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public ExcelExportEnum getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(ExcelExportEnum type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
package com.pig4cloud.pigx.common.poi.exception.excel;
|
||||
|
||||
import com.pig4cloud.pigx.common.poi.exception.excel.enums.ExcelImportEnum;
|
||||
|
||||
/**
|
||||
* 导入异常
|
||||
*
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
*/
|
||||
public class ExcelImportException extends RuntimeException {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private ExcelImportEnum type;
|
||||
|
||||
public ExcelImportException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public ExcelImportException(ExcelImportEnum type) {
|
||||
super(type.getMsg());
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public ExcelImportException(ExcelImportEnum type, Throwable cause) {
|
||||
super(type.getMsg(), cause);
|
||||
}
|
||||
|
||||
public ExcelImportException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public ExcelImportException(String message, ExcelImportEnum type) {
|
||||
super(message);
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public ExcelImportEnum getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(ExcelImportEnum type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
package com.pig4cloud.pigx.common.poi.exception.excel.enums;
|
||||
|
||||
/**
|
||||
* 导出异常类型枚举
|
||||
*
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
*/
|
||||
public enum ExcelExportEnum {
|
||||
|
||||
PARAMETER_ERROR("Excel导出参数错误"),
|
||||
EXPORT_ERROR("Excel导出错误");
|
||||
|
||||
private String msg;
|
||||
|
||||
ExcelExportEnum(String msg) {
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
public String getMsg() {
|
||||
return msg;
|
||||
}
|
||||
|
||||
public void setMsg(String msg) {
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
package com.pig4cloud.pigx.common.poi.exception.excel.enums;
|
||||
|
||||
/**
|
||||
* 导出异常类型枚举
|
||||
*
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
*/
|
||||
public enum ExcelImportEnum {
|
||||
|
||||
GET_VALUE_ERROR("Excel值获取失败"),
|
||||
VERIFY_ERROR("值校验失败");
|
||||
|
||||
private String msg;
|
||||
|
||||
ExcelImportEnum(String msg) {
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
public String getMsg() {
|
||||
return msg;
|
||||
}
|
||||
|
||||
public void setMsg(String msg) {
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
package com.pig4cloud.pigx.common.poi.exception.word;
|
||||
|
||||
import com.pig4cloud.pigx.common.poi.exception.word.enmus.WordExportEnum;
|
||||
|
||||
/**
|
||||
* word导出异常
|
||||
*
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
*/
|
||||
public class WordExportException extends RuntimeException {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public WordExportException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public WordExportException(String msg) {
|
||||
super(msg);
|
||||
}
|
||||
|
||||
public WordExportException(WordExportEnum exception) {
|
||||
super(exception.getMsg());
|
||||
}
|
||||
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
package com.pig4cloud.pigx.common.poi.exception.word.enmus;
|
||||
|
||||
/**
|
||||
* 导出异常枚举
|
||||
*
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
*/
|
||||
public enum WordExportEnum {
|
||||
|
||||
EXCEL_PARAMS_ERROR("Excel导出参数错误"),
|
||||
EXCEL_HEAD_HAVA_NULL("Excel表头有的字段为空"),
|
||||
EXCEL_NO_HEAD("Excel没有表头");
|
||||
|
||||
private String msg;
|
||||
|
||||
WordExportEnum(String msg) {
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
public String getMsg() {
|
||||
return msg;
|
||||
}
|
||||
|
||||
public void setMsg(String msg) {
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
}
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
package com.pig4cloud.pigx.common.poi.handler.impl;
|
||||
|
||||
import com.pig4cloud.pigx.common.poi.handler.inter.IExcelDataHandler;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 数据处理默认实现,返回空
|
||||
*
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
*/
|
||||
public abstract class ExcelDataHandlerDefaultImpl implements IExcelDataHandler {
|
||||
/**
|
||||
* 需要处理的字段
|
||||
*/
|
||||
private String[] needHandlerFields;
|
||||
|
||||
@Override
|
||||
public Object exportHandler(Object obj, String name, Object value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getNeedHandlerFields() {
|
||||
return needHandlerFields;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object importHandler(Object obj, String name, Object value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setNeedHandlerFields(String[] needHandlerFields) {
|
||||
this.needHandlerFields = needHandlerFields;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMapValue(Map<String, Object> map, String originKey, Object value) {
|
||||
map.put(originKey, value);
|
||||
}
|
||||
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
/**
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
* 对接口的抽象的默认实现,避免用户实现过多方法
|
||||
*/
|
||||
package com.pig4cloud.pigx.common.poi.handler.impl;
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
package com.pig4cloud.pigx.common.poi.handler.inter;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Excel 导入导出 数据处理接口
|
||||
*
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
*/
|
||||
public interface IExcelDataHandler {
|
||||
|
||||
/**
|
||||
* 导出处理方法
|
||||
*
|
||||
* @param obj 当前对象
|
||||
* @param name 当前字段名称
|
||||
* @param value 当前值
|
||||
* @return
|
||||
*/
|
||||
Object exportHandler(Object obj, String name, Object value);
|
||||
|
||||
/**
|
||||
* 获取需要处理的字段,导入和导出统一处理了, 减少书写的字段
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String[] getNeedHandlerFields();
|
||||
|
||||
/**
|
||||
* 导入处理方法 当前对象,当前字段名称,当前值
|
||||
*
|
||||
* @param obj 当前对象
|
||||
* @param name 当前字段名称
|
||||
* @param value 当前值
|
||||
* @return
|
||||
*/
|
||||
Object importHandler(Object obj, String name, Object value);
|
||||
|
||||
/**
|
||||
* 设置需要处理的属性列表
|
||||
*
|
||||
* @param fields
|
||||
*/
|
||||
void setNeedHandlerFields(String[] fields);
|
||||
|
||||
/**
|
||||
* 设置Map导入,自定义 put
|
||||
*
|
||||
* @param map
|
||||
* @param originKey
|
||||
* @param value
|
||||
*/
|
||||
void setMapValue(Map<String, Object> map, String originKey, Object value);
|
||||
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
package com.pig4cloud.pigx.common.poi.handler.inter;
|
||||
|
||||
/**
|
||||
* 接口自定义处理类
|
||||
*
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
*/
|
||||
public interface IExcelReadRowHanlder<T> {
|
||||
/**
|
||||
* 处理解析对象
|
||||
*
|
||||
* @param t
|
||||
*/
|
||||
void hanlder(T t);
|
||||
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
package com.pig4cloud.pigx.common.poi.handler.inter;
|
||||
|
||||
import com.pig4cloud.pigx.common.poi.excel.entity.result.ExcelVerifyHanlderResult;
|
||||
|
||||
/**
|
||||
* 导入校验接口
|
||||
*
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
*/
|
||||
public interface IExcelVerifyHandler {
|
||||
|
||||
/**
|
||||
* 获取需要处理的字段,导入和导出统一处理了, 减少书写的字段
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
String[] getNeedVerifyFields();
|
||||
|
||||
/**
|
||||
* 获取需要处理的字段,导入和导出统一处理了, 减少书写的字段
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
void setNeedVerifyFields(String[] arr);
|
||||
|
||||
/**
|
||||
* 导出处理方法
|
||||
*
|
||||
* @param obj 当前对象
|
||||
* @param name 当前字段名称
|
||||
* @param value 当前值
|
||||
* @return
|
||||
*/
|
||||
ExcelVerifyHanlderResult verifyHandler(Object obj, String name, Object value);
|
||||
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
/**
|
||||
* 数据处理中心,对导入导出进行数据处理
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
*/
|
||||
package com.pig4cloud.pigx.common.poi.handler;
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
* 对POI进行封装,通过注解的使用,完成POI的简易重复操作
|
||||
* 通过模板完成较为复杂的操作
|
||||
* 进阶步骤:<br/>
|
||||
* <p>1.了解注解,图片类</p>
|
||||
* <p>2.模板语言</p>
|
||||
* <p>3.模板组合</p>
|
||||
*
|
||||
*/
|
||||
package com.pig4cloud.pigx.common.poi;
|
||||
+292
@@ -0,0 +1,292 @@
|
||||
package com.pig4cloud.pigx.common.poi.util;
|
||||
/**
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
* POI对EXCEL操作工具
|
||||
*/
|
||||
|
||||
import org.apache.poi.hssf.usermodel.HSSFCell;
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
|
||||
import org.apache.poi.ss.usermodel.*;
|
||||
import org.apache.poi.ss.util.CellRangeAddress;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
public class ExcelUtil {
|
||||
|
||||
public static void main(String[] args) {
|
||||
//读取excel数据
|
||||
ArrayList<Map<String, String>> result = ExcelUtil.readExcelToObj("D:\\上传表.xlsx");
|
||||
for (Map<String, String> map : result) {
|
||||
System.out.println(map);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取excel数据
|
||||
*
|
||||
* @param path
|
||||
*/
|
||||
public static ArrayList<Map<String, String>> readExcelToObj(String path) {
|
||||
|
||||
Workbook wb = null;
|
||||
ArrayList<Map<String, String>> result = null;
|
||||
try {
|
||||
wb = WorkbookFactory.create(new File(path));
|
||||
result = readExcel(wb, 0, 2, 0);
|
||||
} catch (InvalidFormatException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取excel文件
|
||||
*
|
||||
* @param wb
|
||||
* @param sheetIndex sheet页下标:从0开始
|
||||
* @param startReadLine 开始读取的行:从0开始
|
||||
* @param tailLine 去除最后读取的行
|
||||
*/
|
||||
public static ArrayList<Map<String, String>> readExcel(Workbook wb, int sheetIndex, int startReadLine, int tailLine) {
|
||||
Sheet sheet = wb.getSheetAt(sheetIndex);
|
||||
Row row = null;
|
||||
ArrayList<Map<String, String>> result = new ArrayList<Map<String, String>>();
|
||||
for (int i = startReadLine; i < sheet.getLastRowNum() - tailLine + 1; i++) {
|
||||
|
||||
row = sheet.getRow(i);
|
||||
Map<String, String> map = new HashMap<String, String>();
|
||||
for (Cell c : row) {
|
||||
String returnStr = "";
|
||||
|
||||
boolean isMerge = isMergedRegion(sheet, i, c.getColumnIndex());
|
||||
//判断是否具有合并单元格
|
||||
if (isMerge) {
|
||||
String rs = getMergedRegionValue(sheet, row.getRowNum(), c.getColumnIndex());
|
||||
returnStr = rs;
|
||||
} else {
|
||||
returnStr = c.getRichStringCellValue().getString();
|
||||
}
|
||||
if (c.getColumnIndex() == 0) {
|
||||
map.put("id", returnStr);
|
||||
} else if (c.getColumnIndex() == 1) {
|
||||
map.put("base", returnStr);
|
||||
} else if (c.getColumnIndex() == 2) {
|
||||
map.put("siteName", returnStr);
|
||||
} else if (c.getColumnIndex() == 3) {
|
||||
map.put("articleName", returnStr);
|
||||
} else if (c.getColumnIndex() == 4) {
|
||||
map.put("mediaName", returnStr);
|
||||
} else if (c.getColumnIndex() == 5) {
|
||||
map.put("mediaUrl", returnStr);
|
||||
} else if (c.getColumnIndex() == 6) {
|
||||
map.put("newsSource", returnStr);
|
||||
} else if (c.getColumnIndex() == 7) {
|
||||
map.put("isRecord", returnStr);
|
||||
} else if (c.getColumnIndex() == 8) {
|
||||
map.put("recordTime", returnStr);
|
||||
} else if (c.getColumnIndex() == 9) {
|
||||
map.put("remark", returnStr);
|
||||
}
|
||||
|
||||
}
|
||||
result.add(map);
|
||||
}
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取合并单元格的值
|
||||
*
|
||||
* @param sheet
|
||||
* @param row
|
||||
* @param column
|
||||
* @return
|
||||
*/
|
||||
public static String getMergedRegionValue(Sheet sheet, int row, int column) {
|
||||
int sheetMergeCount = sheet.getNumMergedRegions();
|
||||
|
||||
for (int i = 0; i < sheetMergeCount; i++) {
|
||||
CellRangeAddress ca = sheet.getMergedRegion(i);
|
||||
int firstColumn = ca.getFirstColumn();
|
||||
int lastColumn = ca.getLastColumn();
|
||||
int firstRow = ca.getFirstRow();
|
||||
int lastRow = ca.getLastRow();
|
||||
|
||||
if (row >= firstRow && row <= lastRow) {
|
||||
|
||||
if (column >= firstColumn && column <= lastColumn) {
|
||||
Row fRow = sheet.getRow(firstRow);
|
||||
Cell fCell = fRow.getCell(firstColumn);
|
||||
return getCellValue(fCell);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断合并了行
|
||||
*
|
||||
* @param sheet
|
||||
* @param row
|
||||
* @param column
|
||||
* @return
|
||||
*/
|
||||
public static boolean isMergedRow(Sheet sheet, int row, int column) {
|
||||
int sheetMergeCount = sheet.getNumMergedRegions();
|
||||
for (int i = 0; i < sheetMergeCount; i++) {
|
||||
CellRangeAddress range = sheet.getMergedRegion(i);
|
||||
int firstColumn = range.getFirstColumn();
|
||||
int lastColumn = range.getLastColumn();
|
||||
int firstRow = range.getFirstRow();
|
||||
int lastRow = range.getLastRow();
|
||||
if (row == firstRow && row == lastRow) {
|
||||
if (column >= firstColumn && column <= lastColumn) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断指定的单元格是否是合并单元格
|
||||
*
|
||||
* @param sheet
|
||||
* @param row 行下标
|
||||
* @param column 列下标
|
||||
* @return
|
||||
*/
|
||||
public static boolean isMergedRegion(Sheet sheet, int row, int column) {
|
||||
int sheetMergeCount = sheet.getNumMergedRegions();
|
||||
for (int i = 0; i < sheetMergeCount; i++) {
|
||||
CellRangeAddress range = sheet.getMergedRegion(i);
|
||||
int firstColumn = range.getFirstColumn();
|
||||
int lastColumn = range.getLastColumn();
|
||||
int firstRow = range.getFirstRow();
|
||||
int lastRow = range.getLastRow();
|
||||
if (row >= firstRow && row <= lastRow) {
|
||||
if (column >= firstColumn && column <= lastColumn) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断sheet页中是否含有合并单元格
|
||||
*
|
||||
* @param sheet
|
||||
* @return
|
||||
*/
|
||||
public static boolean hasMerged(Sheet sheet) {
|
||||
return sheet.getNumMergedRegions() > 0 ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 合并单元格
|
||||
*
|
||||
* @param sheet
|
||||
* @param firstRow 开始行
|
||||
* @param lastRow 结束行
|
||||
* @param firstCol 开始列
|
||||
* @param lastCol 结束列
|
||||
*/
|
||||
public static void mergeRegion(Sheet sheet, int firstRow, int lastRow, int firstCol, int lastCol) {
|
||||
sheet.addMergedRegion(new CellRangeAddress(firstRow, lastRow, firstCol, lastCol));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取单元格的值
|
||||
*
|
||||
* @param cell
|
||||
* @return
|
||||
*/
|
||||
public static String getCellValue(Cell cell) {
|
||||
if (cell == null) return "";
|
||||
if (cell.getCellType() == Cell.CELL_TYPE_STRING) {
|
||||
return cell.getStringCellValue();
|
||||
} else if (cell.getCellType() == Cell.CELL_TYPE_BOOLEAN) {
|
||||
return String.valueOf(cell.getBooleanCellValue());
|
||||
} else if (cell.getCellType() == Cell.CELL_TYPE_FORMULA) {
|
||||
return cell.getCellFormula();
|
||||
} else if (cell.getCellType() == Cell.CELL_TYPE_NUMERIC) {
|
||||
return String.valueOf(cell.getNumericCellValue());
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* 从excel读取内容
|
||||
*/
|
||||
public static void readContent(String fileName) {
|
||||
//判断是否是excel2007格式
|
||||
boolean isE2007 = false;
|
||||
if (fileName.endsWith("xlsx"))
|
||||
isE2007 = true;
|
||||
try {
|
||||
//建立输入流
|
||||
InputStream input = new FileInputStream(fileName);
|
||||
Workbook wb = null;
|
||||
//根据文件格式(2003或者2007)来初始化
|
||||
if (isE2007)
|
||||
wb = new XSSFWorkbook(input);
|
||||
else
|
||||
wb = new HSSFWorkbook(input);
|
||||
//获得第一个表单
|
||||
Sheet sheet = wb.getSheetAt(0);
|
||||
//获得第一个表单的迭代器
|
||||
Iterator<Row> rows = sheet.rowIterator();
|
||||
while (rows.hasNext()) {
|
||||
//获得行数据
|
||||
Row row = rows.next();
|
||||
//获得行号从0开始
|
||||
System.out.println("Row #" + row.getRowNum());
|
||||
//获得第一行的迭代器
|
||||
Iterator<Cell> cells = row.cellIterator();
|
||||
while (cells.hasNext()) {
|
||||
Cell cell = cells.next();
|
||||
System.out.println("Cell #" + cell.getColumnIndex());
|
||||
//根据cell中的类型来输出数据
|
||||
switch (cell.getCellType()) {
|
||||
case HSSFCell.CELL_TYPE_NUMERIC:
|
||||
System.out.println(cell.getNumericCellValue());
|
||||
break;
|
||||
case HSSFCell.CELL_TYPE_STRING:
|
||||
System.out.println(cell.getStringCellValue());
|
||||
break;
|
||||
case HSSFCell.CELL_TYPE_BOOLEAN:
|
||||
System.out.println(cell.getBooleanCellValue());
|
||||
break;
|
||||
case HSSFCell.CELL_TYPE_FORMULA:
|
||||
System.out.println(cell.getCellFormula());
|
||||
break;
|
||||
default:
|
||||
//System.out.println("unsuported sell type======="+cell.getCellType());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
ex.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+229
@@ -0,0 +1,229 @@
|
||||
package com.pig4cloud.pigx.common.poi.util;
|
||||
|
||||
import com.pig4cloud.pigx.common.poi.exception.excel.ExcelExportException;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* EasyPoi的el 表达式支持工具类
|
||||
*
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
*/
|
||||
public final class PoiElUtil {
|
||||
|
||||
public static final String LENGTH = "le:";
|
||||
public static final String FOREACH = "fe:";
|
||||
public static final String FOREACH_NOT_CREATE = "!fe:";
|
||||
public static final String FOREACH_AND_SHIFT = "$fe:";
|
||||
public static final String START_STR = "{{";
|
||||
public static final String END_STR = "}}";
|
||||
public static final String NUMBER_SYMBOL = "n:";
|
||||
public static final String FORMAT_DATE = "fd:";
|
||||
public static final String FORMAT_NUMBER = "fn:";
|
||||
public static final String IF_DELETE = "!if:";
|
||||
public static final String EMPTY = "";
|
||||
public static final String LEFT_BRACKET = "(";
|
||||
public static final String RIGHT_BRACKET = ")";
|
||||
|
||||
private PoiElUtil() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析字符串,支持 le,fd,fn,!if,三目
|
||||
*
|
||||
* @param text
|
||||
* @param map
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static Object eval(String text, Map<String, Object> map) throws Exception {
|
||||
String tempText = new String(text);
|
||||
Object obj = innerEval(text, map);
|
||||
// 如果没有被处理而且这个值找map中存在就处理这个值
|
||||
if (tempText.equals(obj.toString()) && map.containsKey(tempText.split("\\.")[0])) {
|
||||
return PoiPublicUtil.getParamsValue(tempText, map);
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析字符串,支持 le,fd,fn,!if,三目
|
||||
*
|
||||
* @param text
|
||||
* @param map
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static Object innerEval(String text, Map<String, Object> map) throws Exception {
|
||||
if (text.indexOf("?") != -1 && text.indexOf(":") != -1) {
|
||||
return trinocular(text, map);
|
||||
}
|
||||
if (text.indexOf(LENGTH) != -1) {
|
||||
return length(text, map);
|
||||
}
|
||||
if (text.indexOf(FORMAT_DATE) != -1) {
|
||||
return formatDate(text, map);
|
||||
}
|
||||
if (text.indexOf(FORMAT_NUMBER) != -1) {
|
||||
return formatNumber(text, map);
|
||||
}
|
||||
if (text.indexOf(IF_DELETE) != -1) {
|
||||
return ifDelete(text, map);
|
||||
}
|
||||
if (text.startsWith("'")) {
|
||||
return text.replace("'", "");
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是不是删除列
|
||||
*
|
||||
* @param text
|
||||
* @param map
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
private static Object ifDelete(String text, Map<String, Object> map) throws Exception {
|
||||
// 把多个空格变成一个空格
|
||||
text = text.replaceAll("\\s{1,}", " ").trim();
|
||||
String[] keys = getKey(IF_DELETE, text).split(" ");
|
||||
text = text.replace(IF_DELETE, EMPTY);
|
||||
return isTrue(keys, map);
|
||||
}
|
||||
|
||||
/**
|
||||
* 是不是真
|
||||
*
|
||||
* @param keys
|
||||
* @param map
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
private static Boolean isTrue(String[] keys, Map<String, Object> map) throws Exception {
|
||||
if (keys.length == 0) {
|
||||
String constant = null;
|
||||
if ((constant = isConstant(keys[0])) != null) {
|
||||
return Boolean.valueOf(constant);
|
||||
}
|
||||
return Boolean.valueOf(PoiPublicUtil.getParamsValue(keys[0], map).toString());
|
||||
}
|
||||
if (keys.length == 3) {
|
||||
Object first = eval(keys[0], map);
|
||||
Object second = eval(keys[2], map);
|
||||
return PoiFunctionUtil.isTrue(first, keys[1], second);
|
||||
}
|
||||
throw new ExcelExportException("判断参数不对");
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是不是常量
|
||||
*
|
||||
* @param param
|
||||
* @return
|
||||
*/
|
||||
private static String isConstant(String param) {
|
||||
if (param.indexOf("'") != -1) {
|
||||
return param.replace("'", "");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化数字
|
||||
*
|
||||
* @param text
|
||||
* @param map
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
private static Object formatNumber(String text, Map<String, Object> map) throws Exception {
|
||||
String[] key = getKey(FORMAT_NUMBER, text).split(";");
|
||||
text = text.replace(FORMAT_NUMBER, EMPTY);
|
||||
return innerEval(replacinnerEvalue(text, PoiFunctionUtil.formatNumber(PoiPublicUtil.getParamsValue(key[0], map), key[1])), map);
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化时间
|
||||
*
|
||||
* @param text
|
||||
* @param map
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
private static Object formatDate(String text, Map<String, Object> map) throws Exception {
|
||||
String[] key = getKey(FORMAT_DATE, text).split(";");
|
||||
text = text.replace(FORMAT_DATE, EMPTY);
|
||||
return innerEval(replacinnerEvalue(text, PoiFunctionUtil.formatDate(PoiPublicUtil.getParamsValue(key[0], map), key[1])), map);
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算这个的长度
|
||||
*
|
||||
* @param text
|
||||
* @param map
|
||||
* @throws Exception
|
||||
*/
|
||||
private static Object length(String text, Map<String, Object> map) throws Exception {
|
||||
String key = getKey(LENGTH, text);
|
||||
text = text.replace(LENGTH, EMPTY);
|
||||
Object val = PoiPublicUtil.getParamsValue(key, map);
|
||||
return innerEval(replacinnerEvalue(text, PoiFunctionUtil.length(val)), map);
|
||||
}
|
||||
|
||||
private static String replacinnerEvalue(String text, Object val) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(text.substring(0, text.indexOf(LEFT_BRACKET)));
|
||||
sb.append(" ");
|
||||
sb.append(val);
|
||||
sb.append(" ");
|
||||
sb.append(text.substring(text.indexOf(RIGHT_BRACKET) + 1, text.length()));
|
||||
return sb.toString().trim();
|
||||
}
|
||||
|
||||
private static String getKey(String prefix, String text) {
|
||||
int leftBracket = 1, rigthBracket = 0, position = 0;
|
||||
int index = text.indexOf(prefix) + prefix.length();
|
||||
while (text.charAt(index) == " ".charAt(0)) {
|
||||
text = text.substring(0, index) + text.substring(index + 1, text.length());
|
||||
}
|
||||
for (int i = text.indexOf(prefix + LEFT_BRACKET) + prefix.length() + 1; i < text.length(); i++) {
|
||||
if (text.charAt(i) == LEFT_BRACKET.charAt(0)) {
|
||||
leftBracket++;
|
||||
}
|
||||
if (text.charAt(i) == RIGHT_BRACKET.charAt(0)) {
|
||||
rigthBracket++;
|
||||
}
|
||||
if (leftBracket == rigthBracket) {
|
||||
position = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return text.substring(text.indexOf(prefix + LEFT_BRACKET) + 1 + prefix.length(), position).trim();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println(getKey(IF_DELETE, "测试 " + IF_DELETE + " (小明)"));
|
||||
}
|
||||
|
||||
/**
|
||||
* 三目运算
|
||||
*
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
private static Object trinocular(String text, Map<String, Object> map) throws Exception {
|
||||
// 把多个空格变成一个空格
|
||||
text = text.replaceAll("\\s{1,}", " ").trim();
|
||||
String testText = text.substring(0, text.indexOf("?"));
|
||||
text = text.substring(text.indexOf("?") + 1, text.length()).trim();
|
||||
text = innerEval(text, map).toString();
|
||||
String[] keys = text.split(":");
|
||||
Object first = eval(keys[0].trim(), map);
|
||||
Object second = eval(keys[1].trim(), map);
|
||||
return isTrue(testText.split(" "), map) ? first : second;
|
||||
}
|
||||
|
||||
}
|
||||
+153
@@ -0,0 +1,153 @@
|
||||
package com.pig4cloud.pigx.common.poi.util;
|
||||
|
||||
import com.pig4cloud.pigx.common.poi.exception.excel.ExcelExportException;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* if else,length,for each,fromatNumber,formatDate 满足模板的 el 表达式支持
|
||||
*
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
*/
|
||||
public final class PoiFunctionUtil {
|
||||
|
||||
private static final String TWO_DECIMAL_STR = "###.00";
|
||||
private static final String THREE_DECIMAL_STR = "###.000";
|
||||
|
||||
private static final DecimalFormat TWO_DECIMAL = new DecimalFormat(TWO_DECIMAL_STR);
|
||||
private static final DecimalFormat THREE_DECIMAL = new DecimalFormat(THREE_DECIMAL_STR);
|
||||
|
||||
private static final String DAY_STR = "yyyy-MM-dd";
|
||||
private static final String TIME_STR = "yyyy-MM-dd HH:mm:ss";
|
||||
private static final String TIME__NO_S_STR = "yyyy-MM-dd HH:mm";
|
||||
|
||||
private static final SimpleDateFormat DAY_FORMAT = new SimpleDateFormat(DAY_STR);
|
||||
private static final SimpleDateFormat TIME_FORMAT = new SimpleDateFormat(TIME_STR);
|
||||
private static final SimpleDateFormat TIME__NO_S_FORMAT = new SimpleDateFormat(TIME__NO_S_STR);
|
||||
|
||||
private PoiFunctionUtil() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取对象的长度
|
||||
*
|
||||
* @param obj
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
public static int length(Object obj) {
|
||||
if (obj == null) {
|
||||
return 0;
|
||||
}
|
||||
if (obj instanceof Map) {
|
||||
return ((Map) obj).size();
|
||||
}
|
||||
if (obj instanceof Collection) {
|
||||
return ((Collection) obj).size();
|
||||
}
|
||||
if (obj.getClass().isArray()) {
|
||||
return Array.getLength(obj);
|
||||
}
|
||||
return String.valueOf(obj).length();
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化数字
|
||||
*
|
||||
* @param obj
|
||||
* @return
|
||||
* @throws NumberFormatException
|
||||
*/
|
||||
public static String formatNumber(Object obj, String format) {
|
||||
if (obj == null || obj.toString() == "") {
|
||||
return "";
|
||||
}
|
||||
double number = Double.valueOf(obj.toString());
|
||||
DecimalFormat decimalFormat = null;
|
||||
if (TWO_DECIMAL.equals(format)) {
|
||||
decimalFormat = TWO_DECIMAL;
|
||||
} else if (THREE_DECIMAL_STR.equals(format)) {
|
||||
decimalFormat = THREE_DECIMAL;
|
||||
} else {
|
||||
decimalFormat = new DecimalFormat(format);
|
||||
}
|
||||
return decimalFormat.format(number);
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化时间
|
||||
*
|
||||
* @param obj
|
||||
* @return
|
||||
*/
|
||||
public static String formatDate(Object obj, String format) {
|
||||
if (obj == null || obj.toString() == "") {
|
||||
return "";
|
||||
}
|
||||
SimpleDateFormat dateFormat = null;
|
||||
if (DAY_STR.equals(format)) {
|
||||
dateFormat = DAY_FORMAT;
|
||||
} else if (TIME_STR.equals(format)) {
|
||||
dateFormat = TIME_FORMAT;
|
||||
} else if (TIME__NO_S_STR.equals(format)) {
|
||||
dateFormat = TIME__NO_S_FORMAT;
|
||||
} else {
|
||||
dateFormat = new SimpleDateFormat(format);
|
||||
}
|
||||
return dateFormat.format(obj);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是不是成功
|
||||
*
|
||||
* @param first
|
||||
* @param operator
|
||||
* @param second
|
||||
* @return
|
||||
*/
|
||||
public static boolean isTrue(Object first, String operator, Object second) {
|
||||
if (">".endsWith(operator)) {
|
||||
return isGt(first, second);
|
||||
} else if ("<".endsWith(operator)) {
|
||||
return isGt(second, first);
|
||||
} else if ("==".endsWith(operator)) {
|
||||
if (first != null && second != null) {
|
||||
return first.equals(second);
|
||||
}
|
||||
return first == second;
|
||||
} else if ("!=".endsWith(operator)) {
|
||||
if (first != null && second != null) {
|
||||
return !first.equals(second);
|
||||
}
|
||||
return first != second;
|
||||
} else {
|
||||
throw new ExcelExportException("占不支持改操作符");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 前者是不是大于后者
|
||||
*
|
||||
* @param first
|
||||
* @param second
|
||||
* @return
|
||||
*/
|
||||
private static boolean isGt(Object first, Object second) {
|
||||
if (first == null || first.toString() == "") {
|
||||
return false;
|
||||
}
|
||||
if (second == null || second.toString() == "") {
|
||||
return true;
|
||||
}
|
||||
double one = Double.valueOf(first.toString());
|
||||
double two = Double.valueOf(second.toString());
|
||||
return one > two;
|
||||
}
|
||||
|
||||
}
|
||||
+182
@@ -0,0 +1,182 @@
|
||||
package com.pig4cloud.pigx.common.poi.util;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.poi.ss.usermodel.Cell;
|
||||
import org.apache.poi.ss.usermodel.Row;
|
||||
import org.apache.poi.ss.usermodel.Sheet;
|
||||
import org.apache.poi.ss.util.CellRangeAddress;
|
||||
import com.pig4cloud.pigx.common.poi.excel.entity.params.MergeEntity;
|
||||
import com.pig4cloud.pigx.common.poi.exception.excel.ExcelExportException;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 纵向合并单元格工具类
|
||||
*
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
*/
|
||||
public final class PoiMergeCellUtil {
|
||||
|
||||
private PoiMergeCellUtil() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 纵向合并相同内容的单元格
|
||||
*
|
||||
* @param sheet
|
||||
* @param startRow 开始行
|
||||
* @param columns 需要处理的列
|
||||
*/
|
||||
public static void mergeCells(Sheet sheet, int startRow, Integer... columns) {
|
||||
if (columns == null) {
|
||||
throw new ExcelExportException("至少需要处理1列");
|
||||
}
|
||||
Map<Integer, int[]> mergeMap = new HashMap<Integer, int[]>();
|
||||
for (int i = 0; i < columns.length; i++) {
|
||||
mergeMap.put(columns[i], null);
|
||||
}
|
||||
mergeCells(sheet, mergeMap, startRow, sheet.getLastRowNum());
|
||||
}
|
||||
|
||||
/**
|
||||
* 纵向合并相同内容的单元格
|
||||
*
|
||||
* @param sheet
|
||||
* @param mergeMap key--列,value--依赖的列,没有传空
|
||||
* @param startRow 开始行
|
||||
*/
|
||||
public static void mergeCells(Sheet sheet, Map<Integer, int[]> mergeMap, int startRow) {
|
||||
mergeCells(sheet, mergeMap, startRow, sheet.getLastRowNum());
|
||||
}
|
||||
|
||||
/**
|
||||
* 纵向合并相同内容的单元格
|
||||
*
|
||||
* @param sheet
|
||||
* @param mergeMap key--列,value--依赖的列,没有传空
|
||||
* @param startRow 开始行
|
||||
* @param endRow 结束行
|
||||
*/
|
||||
public static void mergeCells(Sheet sheet, Map<Integer, int[]> mergeMap, int startRow, int endRow) {
|
||||
Map<Integer, MergeEntity> mergeDataMap = new HashMap<Integer, MergeEntity>();
|
||||
if (mergeMap.size() == 0) {
|
||||
return;
|
||||
}
|
||||
Row row;
|
||||
Set<Integer> sets = mergeMap.keySet();
|
||||
String text;
|
||||
for (int i = startRow; i <= endRow; i++) {
|
||||
row = sheet.getRow(i);
|
||||
for (Integer index : sets) {
|
||||
if (row == null || row.getCell(index) == null) {
|
||||
if (mergeDataMap.get(index) == null) {
|
||||
continue;
|
||||
}
|
||||
if (mergeDataMap.get(index).getEndRow() == 0) {
|
||||
mergeDataMap.get(index).setEndRow(i - 1);
|
||||
}
|
||||
} else {
|
||||
text = row.getCell(index).getStringCellValue();
|
||||
if (StringUtils.isNotEmpty(text)) {
|
||||
hanlderMergeCells(index, i, text, mergeDataMap, sheet, row.getCell(index), mergeMap.get(index));
|
||||
} else {
|
||||
mergeCellOrContinue(index, mergeDataMap, sheet);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mergeDataMap.size() > 0) {
|
||||
for (Integer index : mergeDataMap.keySet()) {
|
||||
sheet.addMergedRegion(new CellRangeAddress(mergeDataMap.get(index).getStartRow(), mergeDataMap.get(index).getEndRow(), index, index));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理合并单元格
|
||||
*
|
||||
* @param index
|
||||
* @param rowNum
|
||||
* @param text
|
||||
* @param mergeDataMap
|
||||
* @param sheet
|
||||
* @param cell
|
||||
* @param delys
|
||||
*/
|
||||
private static void hanlderMergeCells(Integer index, int rowNum, String text, Map<Integer, MergeEntity> mergeDataMap, Sheet sheet, Cell cell, int[] delys) {
|
||||
if (mergeDataMap.containsKey(index)) {
|
||||
if (checkIsEqualByCellContents(mergeDataMap.get(index), text, cell, delys, rowNum)) {
|
||||
mergeDataMap.get(index).setEndRow(rowNum);
|
||||
} else {
|
||||
sheet.addMergedRegion(new CellRangeAddress(mergeDataMap.get(index).getStartRow(), mergeDataMap.get(index).getEndRow(), index, index));
|
||||
mergeDataMap.put(index, createMergeEntity(text, rowNum, cell, delys));
|
||||
}
|
||||
} else {
|
||||
mergeDataMap.put(index, createMergeEntity(text, rowNum, cell, delys));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 字符为空的情况下判断
|
||||
*
|
||||
* @param index
|
||||
* @param mergeDataMap
|
||||
* @param sheet
|
||||
*/
|
||||
private static void mergeCellOrContinue(Integer index, Map<Integer, MergeEntity> mergeDataMap, Sheet sheet) {
|
||||
if (mergeDataMap.containsKey(index) && mergeDataMap.get(index).getEndRow() != mergeDataMap.get(index).getStartRow()) {
|
||||
sheet.addMergedRegion(new CellRangeAddress(mergeDataMap.get(index).getStartRow(), mergeDataMap.get(index).getEndRow(), index, index));
|
||||
mergeDataMap.remove(index);
|
||||
}
|
||||
}
|
||||
|
||||
private static MergeEntity createMergeEntity(String text, int rowNum, Cell cell, int[] delys) {
|
||||
MergeEntity mergeEntity = new MergeEntity(text, rowNum, rowNum);
|
||||
// 存在依赖关系
|
||||
if (delys != null && delys.length != 0) {
|
||||
List<String> list = new ArrayList<String>(delys.length);
|
||||
mergeEntity.setRelyList(list);
|
||||
for (int i = 0; i < delys.length; i++) {
|
||||
list.add(getCellNotNullText(cell, delys[i], rowNum));
|
||||
}
|
||||
}
|
||||
return mergeEntity;
|
||||
}
|
||||
|
||||
private static boolean checkIsEqualByCellContents(MergeEntity mergeEntity, String text, Cell cell, int[] delys, int rowNum) {
|
||||
// 没有依赖关系
|
||||
if (delys == null || delys.length == 0) {
|
||||
return mergeEntity.getText().equals(text);
|
||||
}
|
||||
// 存在依赖关系
|
||||
if (mergeEntity.getText().equals(text)) {
|
||||
for (int i = 0; i < delys.length; i++) {
|
||||
if (!getCellNotNullText(cell, delys[i], rowNum).equals(mergeEntity.getRelyList().get(i))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取一个单元格的值,确保这个单元格必须有值,不然向上查询
|
||||
*
|
||||
* @param cell
|
||||
* @param index
|
||||
* @param rowNum
|
||||
* @return
|
||||
*/
|
||||
private static String getCellNotNullText(Cell cell, int index, int rowNum) {
|
||||
String temp = cell.getRow().getCell(index).getStringCellValue();
|
||||
while (StringUtils.isEmpty(temp)) {
|
||||
temp = cell.getRow().getSheet().getRow(--rowNum).getCell(index).getStringCellValue();
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
|
||||
}
|
||||
+459
@@ -0,0 +1,459 @@
|
||||
package com.pig4cloud.pigx.common.poi.util;
|
||||
|
||||
import com.pig4cloud.pigx.common.poi.excel.annotation.Excel;
|
||||
import com.pig4cloud.pigx.common.poi.excel.annotation.ExcelCollection;
|
||||
import com.pig4cloud.pigx.common.poi.excel.annotation.ExcelEntity;
|
||||
import com.pig4cloud.pigx.common.poi.excel.annotation.ExcelIgnore;
|
||||
import com.pig4cloud.pigx.common.poi.excel.entity.vo.PoiBaseConstants;
|
||||
import com.pig4cloud.pigx.common.poi.word.entity.WordImageEntity;
|
||||
import com.pig4cloud.pigx.common.poi.word.entity.params.ExcelListEntity;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.poi.POIXMLDocumentPart;
|
||||
import org.apache.poi.hssf.usermodel.*;
|
||||
import org.apache.poi.ss.usermodel.PictureData;
|
||||
import org.apache.poi.xssf.usermodel.*;
|
||||
import org.apache.poi.xwpf.usermodel.XWPFDocument;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTMarker;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* EASYPOI 的公共基础类
|
||||
*
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
*/
|
||||
@Slf4j
|
||||
public final class PoiPublicUtil {
|
||||
|
||||
private PoiPublicUtil() {
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked"})
|
||||
public static <K, V> Map<K, V> mapFor(Object... mapping) {
|
||||
Map<K, V> map = new HashMap<K, V>();
|
||||
for (int i = 0; i < mapping.length; i += 2) {
|
||||
map.put((K) mapping[i], (V) mapping[i + 1]);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* 彻底创建一个对象
|
||||
*
|
||||
* @param clazz
|
||||
* @return
|
||||
*/
|
||||
public static Object createObject(Class<?> clazz, String targetId) {
|
||||
Object obj = null;
|
||||
Method setMethod;
|
||||
try {
|
||||
if (clazz.equals(Map.class)) {
|
||||
return new HashMap<String, Object>();
|
||||
}
|
||||
obj = clazz.newInstance();
|
||||
Field[] fields = getClassFields(clazz);
|
||||
for (Field field : fields) {
|
||||
if (isNotUserExcelUserThis(null, field, targetId)) {
|
||||
continue;
|
||||
}
|
||||
if (isCollection(field.getType())) {
|
||||
ExcelCollection collection = field.getAnnotation(ExcelCollection.class);
|
||||
setMethod = getMethod(field.getName(), clazz, field.getType());
|
||||
setMethod.invoke(obj, collection.type().newInstance());
|
||||
} else if (!isJavaClass(field)) {
|
||||
setMethod = getMethod(field.getName(), clazz, field.getType());
|
||||
setMethod.invoke(obj, createObject(field.getType(), targetId));
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
throw new RuntimeException("创建对象异常");
|
||||
}
|
||||
return obj;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取class的 包括父类的
|
||||
*
|
||||
* @param clazz
|
||||
* @return
|
||||
*/
|
||||
public static Field[] getClassFields(Class<?> clazz) {
|
||||
List<Field> list = new ArrayList<Field>();
|
||||
Field[] fields;
|
||||
do {
|
||||
fields = clazz.getDeclaredFields();
|
||||
for (int i = 0; i < fields.length; i++) {
|
||||
list.add(fields[i]);
|
||||
}
|
||||
clazz = clazz.getSuperclass();
|
||||
} while (clazz != Object.class && clazz != null);
|
||||
return list.toArray(fields);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param photoByte
|
||||
* @return
|
||||
*/
|
||||
public static String getFileExtendName(byte[] photoByte) {
|
||||
String strFileExtendName = "JPG";
|
||||
if ((photoByte[0] == 71) && (photoByte[1] == 73) && (photoByte[2] == 70) && (photoByte[3] == 56) && ((photoByte[4] == 55) || (photoByte[4] == 57)) && (photoByte[5] == 97)) {
|
||||
strFileExtendName = "GIF";
|
||||
} else if ((photoByte[6] == 74) && (photoByte[7] == 70) && (photoByte[8] == 73) && (photoByte[9] == 70)) {
|
||||
strFileExtendName = "JPG";
|
||||
} else if ((photoByte[0] == 66) && (photoByte[1] == 77)) {
|
||||
strFileExtendName = "BMP";
|
||||
} else if ((photoByte[1] == 80) && (photoByte[2] == 78) && (photoByte[3] == 71)) {
|
||||
strFileExtendName = "PNG";
|
||||
}
|
||||
return strFileExtendName;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取GET方法
|
||||
*
|
||||
* @param name
|
||||
* @param pojoClass
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static Method getMethod(String name, Class<?> pojoClass) throws Exception {
|
||||
StringBuffer getMethodName = new StringBuffer(PoiBaseConstants.GET);
|
||||
getMethodName.append(name.substring(0, 1).toUpperCase());
|
||||
getMethodName.append(name.substring(1));
|
||||
Method method = null;
|
||||
try {
|
||||
method = pojoClass.getMethod(getMethodName.toString(), new Class[]{});
|
||||
} catch (Exception e) {
|
||||
method = pojoClass.getMethod(getMethodName.toString().replace(PoiBaseConstants.GET, PoiBaseConstants.IS), new Class[]{});
|
||||
}
|
||||
return method;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取SET方法
|
||||
*
|
||||
* @param name
|
||||
* @param pojoClass
|
||||
* @param type
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static Method getMethod(String name, Class<?> pojoClass, Class<?> type) throws Exception {
|
||||
StringBuffer getMethodName = new StringBuffer(PoiBaseConstants.SET);
|
||||
getMethodName.append(name.substring(0, 1).toUpperCase());
|
||||
getMethodName.append(name.substring(1));
|
||||
return pojoClass.getMethod(getMethodName.toString(), new Class[]{type});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取get方法 通过EXCEL注解exportConvert判断是否支持值的转换
|
||||
*
|
||||
* @param name
|
||||
* @param pojoClass
|
||||
* @param convert
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static Method getMethod(String name, Class<?> pojoClass, boolean convert) throws Exception {
|
||||
StringBuffer getMethodName = new StringBuffer();
|
||||
if (convert) {
|
||||
getMethodName.append(PoiBaseConstants.CONVERT);
|
||||
}
|
||||
getMethodName.append(PoiBaseConstants.GET);
|
||||
getMethodName.append(name.substring(0, 1).toUpperCase());
|
||||
getMethodName.append(name.substring(1));
|
||||
Method method = null;
|
||||
try {
|
||||
method = pojoClass.getMethod(getMethodName.toString(), new Class[]{});
|
||||
} catch (Exception e) {
|
||||
method = pojoClass.getMethod(getMethodName.toString().replace(PoiBaseConstants.GET, PoiBaseConstants.IS), new Class[]{});
|
||||
}
|
||||
return method;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取set方法 通过EXCEL注解importConvert判断是否支持值的转换
|
||||
*
|
||||
* @param name
|
||||
* @param pojoClass
|
||||
* @param type
|
||||
* @param convert
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static Method getMethod(String name, Class<?> pojoClass, Class<?> type, boolean convert) throws Exception {
|
||||
StringBuffer setMethodName = new StringBuffer();
|
||||
if (convert) {
|
||||
setMethodName.append(PoiBaseConstants.CONVERT);
|
||||
}
|
||||
setMethodName.append(PoiBaseConstants.SET);
|
||||
setMethodName.append(name.substring(0, 1).toUpperCase());
|
||||
setMethodName.append(name.substring(1));
|
||||
return pojoClass.getMethod(setMethodName.toString(), new Class[]{type});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Excel2003图片
|
||||
*
|
||||
* @param sheet 当前sheet对象
|
||||
* @param workbook 工作簿对象
|
||||
* @return Map key:图片单元格索引(1_1)String,value:图片流PictureData
|
||||
*/
|
||||
public static Map<String, PictureData> getSheetPictrues03(HSSFSheet sheet, HSSFWorkbook workbook) {
|
||||
Map<String, PictureData> sheetIndexPicMap = new HashMap<String, PictureData>();
|
||||
List<HSSFPictureData> pictures = workbook.getAllPictures();
|
||||
if (!pictures.isEmpty()) {
|
||||
for (HSSFShape shape : sheet.getDrawingPatriarch().getChildren()) {
|
||||
HSSFClientAnchor anchor = (HSSFClientAnchor) shape.getAnchor();
|
||||
if (shape instanceof HSSFPicture) {
|
||||
HSSFPicture pic = (HSSFPicture) shape;
|
||||
int pictureIndex = pic.getPictureIndex() - 1;
|
||||
HSSFPictureData picData = pictures.get(pictureIndex);
|
||||
String picIndex = String.valueOf(anchor.getRow1()) + "_" + String.valueOf(anchor.getCol1());
|
||||
sheetIndexPicMap.put(picIndex, picData);
|
||||
}
|
||||
}
|
||||
return sheetIndexPicMap;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取Excel2007图片
|
||||
*
|
||||
* @param sheet 当前sheet对象
|
||||
* @param workbook 工作簿对象
|
||||
* @return Map key:图片单元格索引(1_1)String,value:图片流PictureData
|
||||
*/
|
||||
public static Map<String, PictureData> getSheetPictrues07(XSSFSheet sheet, XSSFWorkbook workbook) {
|
||||
Map<String, PictureData> sheetIndexPicMap = new HashMap<String, PictureData>();
|
||||
for (POIXMLDocumentPart dr : sheet.getRelations()) {
|
||||
if (dr instanceof XSSFDrawing) {
|
||||
XSSFDrawing drawing = (XSSFDrawing) dr;
|
||||
List<XSSFShape> shapes = drawing.getShapes();
|
||||
for (XSSFShape shape : shapes) {
|
||||
XSSFPicture pic = (XSSFPicture) shape;
|
||||
XSSFClientAnchor anchor = pic.getPreferredSize();
|
||||
CTMarker ctMarker = anchor.getFrom();
|
||||
String picIndex = ctMarker.getRow() + "_" + ctMarker.getCol();
|
||||
sheetIndexPicMap.put(picIndex, pic.getPictureData());
|
||||
}
|
||||
}
|
||||
}
|
||||
return sheetIndexPicMap;
|
||||
}
|
||||
|
||||
public static String getWebRootPath(String filePath) {
|
||||
// String path = PoiPublicUtil.class.getClassLoader().getResource("").toURI().getPath();
|
||||
String path = ClassUtils.getDefaultClassLoader().getResource("").getPath();
|
||||
log.debug("--- getWebRootPath ----filePath--- " + path);
|
||||
path = path.replace("WEB-INF/classes/", "");
|
||||
path = path.replace("file:/", "");
|
||||
log.debug("--- path--- " + path);
|
||||
log.debug("--- filePath--- " + filePath);
|
||||
return path + filePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是不是集合的实现类
|
||||
*
|
||||
* @param clazz
|
||||
* @return
|
||||
*/
|
||||
public static boolean isCollection(Class<?> clazz) {
|
||||
return Collection.class.isAssignableFrom(clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
* 是不是java基础类
|
||||
*
|
||||
* @param field
|
||||
* @return
|
||||
*/
|
||||
public static boolean isJavaClass(Field field) {
|
||||
Class<?> fieldType = field.getType();
|
||||
boolean isBaseClass = false;
|
||||
if (fieldType.isArray()) {
|
||||
isBaseClass = false;
|
||||
} else if (fieldType.isPrimitive() || fieldType.getPackage() == null || fieldType.getPackage().getName().equals("java.lang") || fieldType.getPackage().getName().equals("java.math") || fieldType.getPackage().getName().equals("java.sql") || fieldType.getPackage().getName().equals("java.util")) {
|
||||
isBaseClass = true;
|
||||
}
|
||||
return isBaseClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否不要在这个excel操作中
|
||||
*
|
||||
* @param
|
||||
* @param field
|
||||
* @param targetId
|
||||
* @return
|
||||
*/
|
||||
public static boolean isNotUserExcelUserThis(List<String> exclusionsList, Field field, String targetId) {
|
||||
boolean boo = true;
|
||||
if (field.getAnnotation(ExcelIgnore.class) != null) {
|
||||
boo = true;
|
||||
} else if (boo && field.getAnnotation(ExcelCollection.class) != null && isUseInThis(field.getAnnotation(ExcelCollection.class).name(), targetId) && (exclusionsList == null || !exclusionsList.contains(field.getAnnotation(ExcelCollection.class).name()))) {
|
||||
boo = false;
|
||||
} else if (boo && field.getAnnotation(Excel.class) != null && isUseInThis(field.getAnnotation(Excel.class).name(), targetId) && (exclusionsList == null || !exclusionsList.contains(field.getAnnotation(Excel.class).name()))) {
|
||||
boo = false;
|
||||
} else if (boo && field.getAnnotation(ExcelEntity.class) != null && isUseInThis(field.getAnnotation(ExcelEntity.class).name(), targetId) && (exclusionsList == null || !exclusionsList.contains(field.getAnnotation(ExcelEntity.class).name()))) {
|
||||
boo = false;
|
||||
}
|
||||
return boo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是不是使用
|
||||
*
|
||||
* @param exportName
|
||||
* @param targetId
|
||||
* @return
|
||||
*/
|
||||
private static boolean isUseInThis(String exportName, String targetId) {
|
||||
return targetId == null || exportName.equals("") || exportName.indexOf("_") < 0 || exportName.indexOf(targetId) != -1;
|
||||
}
|
||||
|
||||
private static Integer getImageType(String type) {
|
||||
if (type.equalsIgnoreCase("JPG") || type.equalsIgnoreCase("JPEG")) {
|
||||
return XWPFDocument.PICTURE_TYPE_JPEG;
|
||||
}
|
||||
if (type.equalsIgnoreCase("GIF")) {
|
||||
return XWPFDocument.PICTURE_TYPE_GIF;
|
||||
}
|
||||
if (type.equalsIgnoreCase("BMP")) {
|
||||
return XWPFDocument.PICTURE_TYPE_GIF;
|
||||
}
|
||||
if (type.equalsIgnoreCase("PNG")) {
|
||||
return XWPFDocument.PICTURE_TYPE_PNG;
|
||||
}
|
||||
return XWPFDocument.PICTURE_TYPE_JPEG;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回流和图片类型
|
||||
*
|
||||
* @param entity
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static Object[] getIsAndType(WordImageEntity entity) throws Exception {
|
||||
Object[] result = new Object[2];
|
||||
String type;
|
||||
if (entity.getType().equals(WordImageEntity.URL)) {
|
||||
ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream();
|
||||
BufferedImage bufferImg;
|
||||
String path = Thread.currentThread().getContextClassLoader().getResource("").toURI().getPath() + entity.getUrl();
|
||||
path = path.replace("WEB-INF/classes/", "");
|
||||
path = path.replace("file:/", "");
|
||||
bufferImg = ImageIO.read(new File(path));
|
||||
ImageIO.write(bufferImg, entity.getUrl().substring(entity.getUrl().indexOf(".") + 1, entity.getUrl().length()), byteArrayOut);
|
||||
result[0] = byteArrayOut.toByteArray();
|
||||
type = entity.getUrl().split("/.")[entity.getUrl().split("/.").length - 1];
|
||||
} else {
|
||||
result[0] = entity.getData();
|
||||
type = PoiPublicUtil.getFileExtendName(entity.getData());
|
||||
}
|
||||
result[1] = getImageType(type);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取参数值
|
||||
*
|
||||
* @param params
|
||||
* @param map
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
public static Object getParamsValue(String params, Object object) throws Exception {
|
||||
if (params.indexOf(".") != -1) {
|
||||
String[] paramsArr = params.split("\\.");
|
||||
return getValueDoWhile(object, paramsArr, 0);
|
||||
}
|
||||
if (object instanceof Map) {
|
||||
return ((Map) object).get(params);
|
||||
}
|
||||
return getMethod(params, object.getClass()).invoke(object, new Object[]{});
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析数据
|
||||
*
|
||||
* @param currentText
|
||||
* @param map
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static Object getRealValue(String currentText, Map<String, Object> map) throws Exception {
|
||||
String params = "";
|
||||
while (currentText.indexOf("{{") != -1) {
|
||||
params = currentText.substring(currentText.indexOf("{{") + 2, currentText.indexOf("}}"));
|
||||
Object obj = getParamsValue(params.trim(), map);
|
||||
// 判断图片或者是集合
|
||||
|
||||
if (obj instanceof WordImageEntity || obj instanceof List || obj instanceof ExcelListEntity) {
|
||||
return obj;
|
||||
} else {
|
||||
currentText = currentText.replace("{{" + params + "}}", obj.toString());
|
||||
}
|
||||
}
|
||||
return currentText;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过遍历过去对象值
|
||||
*
|
||||
* @param object
|
||||
* @param paramsArr
|
||||
* @param index
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
@SuppressWarnings("rawtypes")
|
||||
public static Object getValueDoWhile(Object object, String[] paramsArr, int index) throws Exception {
|
||||
if (object == null) {
|
||||
return "";
|
||||
}
|
||||
if (object instanceof WordImageEntity) {
|
||||
return object;
|
||||
}
|
||||
if (object instanceof Map) {
|
||||
object = ((Map) object).get(paramsArr[index]);
|
||||
} else {
|
||||
object = getMethod(paramsArr[index], object.getClass()).invoke(object, new Object[]{});
|
||||
}
|
||||
return (index == paramsArr.length - 1) ? (object == null ? "" : object) : getValueDoWhile(object, paramsArr, ++index);
|
||||
}
|
||||
|
||||
/**
|
||||
* double to String 防止科学计数法
|
||||
*
|
||||
* @param value
|
||||
* @return
|
||||
*/
|
||||
public static String doubleToString(Double value) {
|
||||
String temp = value.toString();
|
||||
if (temp.contains("E")) {
|
||||
BigDecimal bigDecimal = new BigDecimal(temp);
|
||||
temp = bigDecimal.toPlainString();
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
|
||||
}
|
||||
+94
@@ -0,0 +1,94 @@
|
||||
package com.pig4cloud.pigx.common.poi.util;
|
||||
|
||||
import org.apache.poi.ss.usermodel.Cell;
|
||||
import org.apache.poi.ss.usermodel.Row;
|
||||
import org.apache.poi.ss.usermodel.Sheet;
|
||||
|
||||
/**
|
||||
* Helper functions to aid in the management of sheets
|
||||
* 国外的,不过也不好,慎用,效率不行 TODO
|
||||
*
|
||||
* @author: 国外
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
*/
|
||||
public class PoiSheetUtility extends Object {
|
||||
|
||||
/**
|
||||
* Given a sheet, this method deletes a column from a sheet and moves all
|
||||
* the columns to the right of it to the left one cell.
|
||||
* <p>
|
||||
* Note, this method will not update any formula references.
|
||||
*
|
||||
* @param sheet
|
||||
* @param columnToDelete
|
||||
*/
|
||||
public static void deleteColumn(Sheet sheet, int columnToDelete) {
|
||||
int maxColumn = 0;
|
||||
for (int r = 0; r < sheet.getLastRowNum() + 1; r++) {
|
||||
Row row = sheet.getRow(r);
|
||||
|
||||
// if no row exists here; then nothing to do; next!
|
||||
if (row == null)
|
||||
continue;
|
||||
|
||||
// if the row doesn't have this many columns then we are good; next!
|
||||
int lastColumn = row.getLastCellNum();
|
||||
if (lastColumn > maxColumn)
|
||||
maxColumn = lastColumn;
|
||||
|
||||
if (lastColumn < columnToDelete)
|
||||
continue;
|
||||
|
||||
for (int x = columnToDelete + 1; x < lastColumn + 1; x++) {
|
||||
Cell oldCell = row.getCell(x - 1);
|
||||
if (oldCell != null)
|
||||
row.removeCell(oldCell);
|
||||
|
||||
Cell nextCell = row.getCell(x);
|
||||
if (nextCell != null) {
|
||||
Cell newCell = row.createCell(x - 1, nextCell.getCellType());
|
||||
cloneCell(newCell, nextCell);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Adjust the column widths
|
||||
for (int c = 0; c < maxColumn; c++) {
|
||||
sheet.setColumnWidth(c, sheet.getColumnWidth(c + 1));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Takes an existing Cell and merges all the styles and forumla into the new
|
||||
* one
|
||||
*/
|
||||
private static void cloneCell(Cell cNew, Cell cOld) {
|
||||
cNew.setCellComment(cOld.getCellComment());
|
||||
cNew.setCellStyle(cOld.getCellStyle());
|
||||
|
||||
switch (cNew.getCellType()) {
|
||||
case Cell.CELL_TYPE_BOOLEAN: {
|
||||
cNew.setCellValue(cOld.getBooleanCellValue());
|
||||
break;
|
||||
}
|
||||
case Cell.CELL_TYPE_NUMERIC: {
|
||||
cNew.setCellValue(cOld.getNumericCellValue());
|
||||
break;
|
||||
}
|
||||
case Cell.CELL_TYPE_STRING: {
|
||||
cNew.setCellValue(cOld.getStringCellValue());
|
||||
break;
|
||||
}
|
||||
case Cell.CELL_TYPE_ERROR: {
|
||||
cNew.setCellValue(cOld.getErrorCellValue());
|
||||
break;
|
||||
}
|
||||
case Cell.CELL_TYPE_FORMULA: {
|
||||
cNew.setCellFormula(cOld.getCellFormula());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+43
@@ -0,0 +1,43 @@
|
||||
package com.pig4cloud.pigx.common.poi.word;
|
||||
|
||||
import org.apache.poi.xwpf.usermodel.XWPFDocument;
|
||||
import com.pig4cloud.pigx.common.poi.word.parse.ParseWord07;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Word使用模板导出工具类
|
||||
*
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
*/
|
||||
public final class WordExportUtil {
|
||||
|
||||
private WordExportUtil() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析Word2007版本
|
||||
*
|
||||
* @param url 模板地址
|
||||
* @param map 解析数据源
|
||||
* @return
|
||||
*/
|
||||
public static XWPFDocument exportWord07(String url, Map<String, Object> map) throws Exception {
|
||||
return new ParseWord07().parseWord(url, map);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析Word2007版本
|
||||
*
|
||||
* @param document 模板
|
||||
* @param map 解析数据源
|
||||
* @return
|
||||
*/
|
||||
public static void exportWord07(XWPFDocument document, Map<String, Object> map) throws Exception {
|
||||
new ParseWord07().parseWord(document, map);
|
||||
}
|
||||
|
||||
}
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
package com.pig4cloud.pigx.common.poi.word.entity;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.poi.openxml4j.opc.OPCPackage;
|
||||
import org.apache.poi.xwpf.usermodel.XWPFDocument;
|
||||
import org.apache.poi.xwpf.usermodel.XWPFRun;
|
||||
import org.apache.xmlbeans.XmlException;
|
||||
import org.apache.xmlbeans.XmlToken;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D;
|
||||
import org.openxmlformats.schemas.drawingml.x2006.wordprocessingDrawing.CTInline;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* 扩充document,修复图片插入失败问题问题
|
||||
*
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
*/
|
||||
@Slf4j
|
||||
public class MyXWPFDocument extends XWPFDocument {
|
||||
|
||||
private static String PICXML = ""
|
||||
+ "<a:graphic xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\">"
|
||||
+ " <a:graphicData uri=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">"
|
||||
+ " <pic:pic xmlns:pic=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">"
|
||||
+ " <pic:nvPicPr>" + " <pic:cNvPr id=\"%s\" name=\"Generated\"/>" + " <pic:cNvPicPr/>" + " </pic:nvPicPr>" + " <pic:blipFill>" + " <a:blip r:embed=\"%s\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"/>" + " <a:stretch>" + " <a:fillRect/>" + " </a:stretch>" + " </pic:blipFill>" + " <pic:spPr>" + " <a:xfrm>"
|
||||
+ " <a:off x=\"0\" y=\"0\"/>"
|
||||
+ " <a:ext cx=\"%s\" cy=\"%s\"/>" + " </a:xfrm>"
|
||||
+ " <a:prstGeom prst=\"rect\">" + " <a:avLst/>"
|
||||
+ " </a:prstGeom>" + " </pic:spPr>"
|
||||
+ " </pic:pic>"
|
||||
+ " </a:graphicData>" + "</a:graphic>";
|
||||
|
||||
public MyXWPFDocument() {
|
||||
super();
|
||||
}
|
||||
|
||||
public MyXWPFDocument(InputStream in) throws Exception {
|
||||
super(in);
|
||||
}
|
||||
|
||||
public MyXWPFDocument(OPCPackage opcPackage) throws Exception {
|
||||
super(opcPackage);
|
||||
}
|
||||
|
||||
public void createPicture(String blipId, int id, int width, int height) {
|
||||
final int EMU = 9525;
|
||||
width *= EMU;
|
||||
height *= EMU;
|
||||
CTInline inline = createParagraph().createRun().getCTR().addNewDrawing().addNewInline();
|
||||
String picXml = String.format(PICXML, id, blipId, width, height);
|
||||
XmlToken xmlToken = null;
|
||||
try {
|
||||
xmlToken = XmlToken.Factory.parse(picXml);
|
||||
} catch (XmlException xe) {
|
||||
log.error(xe.getMessage(), xe.fillInStackTrace());
|
||||
}
|
||||
inline.set(xmlToken);
|
||||
|
||||
inline.setDistT(0);
|
||||
inline.setDistB(0);
|
||||
inline.setDistL(0);
|
||||
inline.setDistR(0);
|
||||
|
||||
CTPositiveSize2D extent = inline.addNewExtent();
|
||||
extent.setCx(width);
|
||||
extent.setCy(height);
|
||||
|
||||
CTNonVisualDrawingProps docPr = inline.addNewDocPr();
|
||||
docPr.setId(id);
|
||||
docPr.setName("Picture " + id);
|
||||
docPr.setDescr("Generated");
|
||||
}
|
||||
|
||||
public void createPicture(XWPFRun run, String blipId, int id, int width, int height) {
|
||||
final int EMU = 9525;
|
||||
width *= EMU;
|
||||
height *= EMU;
|
||||
CTInline inline = run.getCTR().addNewDrawing().addNewInline();
|
||||
String picXml = String.format(PICXML, id, blipId, width, height);
|
||||
XmlToken xmlToken = null;
|
||||
try {
|
||||
xmlToken = XmlToken.Factory.parse(picXml);
|
||||
} catch (XmlException xe) {
|
||||
log.error(xe.getMessage(), xe.fillInStackTrace());
|
||||
}
|
||||
inline.set(xmlToken);
|
||||
|
||||
inline.setDistT(0);
|
||||
inline.setDistB(0);
|
||||
inline.setDistL(0);
|
||||
inline.setDistR(0);
|
||||
|
||||
CTPositiveSize2D extent = inline.addNewExtent();
|
||||
extent.setCx(width);
|
||||
extent.setCy(height);
|
||||
|
||||
CTNonVisualDrawingProps docPr = inline.addNewDocPr();
|
||||
docPr.setId(id);
|
||||
docPr.setName("Picture " + id);
|
||||
docPr.setDescr("Generated");
|
||||
}
|
||||
|
||||
}
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
package com.pig4cloud.pigx.common.poi.word.entity;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* word导出,图片设置和图片信息
|
||||
*
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
*/
|
||||
@Data
|
||||
public class WordImageEntity {
|
||||
/**
|
||||
* 地址
|
||||
*/
|
||||
public static String URL = "url";
|
||||
/**
|
||||
* 数据
|
||||
*/
|
||||
public static String Data = "data";
|
||||
/**
|
||||
* 图片输入方式
|
||||
*/
|
||||
private String type = URL;
|
||||
/**
|
||||
* 图片宽度
|
||||
*/
|
||||
private int width;
|
||||
/**
|
||||
* 图片高度
|
||||
*/
|
||||
private int height;
|
||||
/**
|
||||
* 图片地址
|
||||
*/
|
||||
private String url;
|
||||
/**
|
||||
* 图片信息
|
||||
*/
|
||||
private byte[] data;
|
||||
|
||||
public WordImageEntity() {
|
||||
|
||||
}
|
||||
|
||||
public WordImageEntity(byte[] data, int width, int height) {
|
||||
this.data = data;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.type = Data;
|
||||
}
|
||||
|
||||
public WordImageEntity(String url, int width, int height) {
|
||||
this.url = url;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
}
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
package com.pig4cloud.pigx.common.poi.word.entity.params;
|
||||
|
||||
import com.pig4cloud.pigx.common.poi.excel.entity.ExcelBaseParams;
|
||||
import com.pig4cloud.pigx.common.poi.handler.inter.IExcelDataHandler;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
* Excel 导出对象
|
||||
*/
|
||||
public class ExcelListEntity extends ExcelBaseParams {
|
||||
|
||||
/**
|
||||
* 数据源
|
||||
*/
|
||||
private List<?> list;
|
||||
|
||||
/**
|
||||
* 实体类对象
|
||||
*/
|
||||
private Class<?> clazz;
|
||||
|
||||
/**
|
||||
* 表头行数
|
||||
*/
|
||||
private int headRows = 1;
|
||||
|
||||
public ExcelListEntity() {
|
||||
|
||||
}
|
||||
|
||||
public ExcelListEntity(List<?> list, Class<?> clazz) {
|
||||
this.list = list;
|
||||
this.clazz = clazz;
|
||||
}
|
||||
|
||||
public ExcelListEntity(List<?> list, Class<?> clazz, IExcelDataHandler dataHanlder) {
|
||||
this.list = list;
|
||||
this.clazz = clazz;
|
||||
setDataHanlder(dataHanlder);
|
||||
}
|
||||
|
||||
public ExcelListEntity(List<?> list, Class<?> clazz, IExcelDataHandler dataHanlder, int headRows) {
|
||||
this.list = list;
|
||||
this.clazz = clazz;
|
||||
this.headRows = headRows;
|
||||
setDataHanlder(dataHanlder);
|
||||
}
|
||||
|
||||
public ExcelListEntity(List<?> list, Class<?> clazz, int headRows) {
|
||||
this.list = list;
|
||||
this.clazz = clazz;
|
||||
this.headRows = headRows;
|
||||
}
|
||||
|
||||
public Class<?> getClazz() {
|
||||
return clazz;
|
||||
}
|
||||
|
||||
public int getHeadRows() {
|
||||
return headRows;
|
||||
}
|
||||
|
||||
public List<?> getList() {
|
||||
return list;
|
||||
}
|
||||
|
||||
public void setClazz(Class<?> clazz) {
|
||||
this.clazz = clazz;
|
||||
}
|
||||
|
||||
public void setHeadRows(int headRows) {
|
||||
this.headRows = headRows;
|
||||
}
|
||||
|
||||
public void setList(List<?> list) {
|
||||
this.list = list;
|
||||
}
|
||||
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
package com.pig4cloud.pigx.common.poi.word.entity.params;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* Excel 对象导出结构
|
||||
*
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
*/
|
||||
@Data
|
||||
public class ListParamEntity {
|
||||
/**
|
||||
* 唯一值,在遍历中重复使用
|
||||
*/
|
||||
public static final String SINGLE = "single";
|
||||
/**
|
||||
* 属于数组类型
|
||||
*/
|
||||
public static final String LIST = "list";
|
||||
/**
|
||||
* 属性名称
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 目标
|
||||
*/
|
||||
private String target;
|
||||
/**
|
||||
* 当是唯一值的时候直接求出值
|
||||
*/
|
||||
private Object value;
|
||||
/**
|
||||
* 数据类型,SINGLE || LIST
|
||||
*/
|
||||
private String type;
|
||||
|
||||
public ListParamEntity() {
|
||||
|
||||
}
|
||||
|
||||
public ListParamEntity(String name, Object value) {
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
this.type = LIST;
|
||||
}
|
||||
|
||||
public ListParamEntity(String name, String target) {
|
||||
this.name = name;
|
||||
this.target = target;
|
||||
this.type = LIST;
|
||||
}
|
||||
|
||||
}
|
||||
+259
@@ -0,0 +1,259 @@
|
||||
package com.pig4cloud.pigx.common.poi.word.parse;
|
||||
|
||||
import com.pig4cloud.pigx.common.poi.cache.WordCache;
|
||||
import com.pig4cloud.pigx.common.poi.util.PoiPublicUtil;
|
||||
import com.pig4cloud.pigx.common.poi.word.entity.MyXWPFDocument;
|
||||
import com.pig4cloud.pigx.common.poi.word.entity.WordImageEntity;
|
||||
import com.pig4cloud.pigx.common.poi.word.entity.params.ExcelListEntity;
|
||||
import com.pig4cloud.pigx.common.poi.word.parse.excel.ExcelEntityParse;
|
||||
import com.pig4cloud.pigx.common.poi.word.parse.excel.ExcelMapParse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.poi.xwpf.usermodel.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 解析07版的Word,替换文字,生成表格,生成图片
|
||||
*
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
*/
|
||||
@Slf4j
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public class ParseWord07 {
|
||||
|
||||
/**
|
||||
* 添加图片
|
||||
*
|
||||
* @param obj
|
||||
* @param currentRun
|
||||
* @throws Exception
|
||||
*/
|
||||
private void addAnImage(WordImageEntity obj, XWPFRun currentRun) throws Exception {
|
||||
Object[] isAndType = PoiPublicUtil.getIsAndType(obj);
|
||||
String picId;
|
||||
try {
|
||||
picId = currentRun.getParagraph().getDocument().addPictureData((byte[]) isAndType[0], (Integer) isAndType[1]);
|
||||
((MyXWPFDocument) currentRun.getParagraph().getDocument()).createPicture(currentRun, picId, currentRun.getParagraph().getDocument().getNextPicNameNumber((Integer) isAndType[1]), obj.getWidth(), obj.getHeight());
|
||||
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据条件改变值
|
||||
*
|
||||
* @param paragraph
|
||||
* @param currentRun
|
||||
* @param currentText
|
||||
* @param runIndex
|
||||
* @param map
|
||||
* @throws Exception
|
||||
*/
|
||||
private void changeValues(XWPFParagraph paragraph, XWPFRun currentRun, String currentText, List<Integer> runIndex, Map<String, Object> map) throws Exception {
|
||||
Object obj = PoiPublicUtil.getRealValue(currentText, map);
|
||||
if (obj instanceof WordImageEntity) {// 如果是图片就设置为图片
|
||||
currentRun.setText("", 0);
|
||||
addAnImage((WordImageEntity) obj, currentRun);
|
||||
} else {
|
||||
currentText = obj.toString();
|
||||
currentRun.setText(currentText, 0);
|
||||
}
|
||||
for (int k = 0; k < runIndex.size(); k++) {
|
||||
paragraph.getRuns().get(runIndex.get(k)).setText("", 0);
|
||||
}
|
||||
runIndex.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是不是迭代输出
|
||||
*
|
||||
* @param cell
|
||||
* @param map
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
private Object checkThisTableIsNeedIterator(XWPFTableCell cell, Map<String, Object> map) throws Exception {
|
||||
String text = cell.getText().trim();
|
||||
// 判断是不是迭代输出
|
||||
if (text.startsWith("{{") && text.endsWith("}}") && text.indexOf("in ") != -1) {
|
||||
return PoiPublicUtil.getRealValue(text.replace("in ", "").trim(), map);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析所有的文本
|
||||
*
|
||||
* @param paragraphs
|
||||
* @param map
|
||||
* @throws Exception
|
||||
*/
|
||||
private void parseAllParagraphic(List<XWPFParagraph> paragraphs, Map<String, Object> map) throws Exception {
|
||||
XWPFParagraph paragraph;
|
||||
for (int i = 0; i < paragraphs.size(); i++) {
|
||||
paragraph = paragraphs.get(i);
|
||||
if (paragraph.getText().indexOf("{{") != -1) {
|
||||
parseThisParagraph(paragraph, map);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析这个段落
|
||||
* @param paragraph
|
||||
* @param map
|
||||
* @throws Exception
|
||||
*/
|
||||
private void parseThisParagraph(XWPFParagraph paragraph, Map<String, Object> map) throws Exception {
|
||||
XWPFRun run;
|
||||
XWPFRun currentRun = null;// 拿到的第一个run,用来set值,可以保存格式
|
||||
String currentText = "";// 存放当前的text
|
||||
String text;
|
||||
Boolean isfinde = false;// 判断是不是已经遇到{{
|
||||
List<Integer> runIndex = new ArrayList<Integer>();// 存储遇到的run,把他们置空
|
||||
for (int i = 0; i < paragraph.getRuns().size(); i++) {
|
||||
run = paragraph.getRuns().get(i);
|
||||
text = run.getText(0);
|
||||
if (StringUtils.isEmpty(text)) {
|
||||
continue;
|
||||
}// 如果为空或者""这种这继续循环跳过
|
||||
if (isfinde) {
|
||||
currentText += text;
|
||||
if (currentText.indexOf("{{") == -1) {
|
||||
isfinde = false;
|
||||
runIndex.clear();
|
||||
} else {
|
||||
runIndex.add(i);
|
||||
}
|
||||
if (currentText.indexOf("}}") != -1) {
|
||||
changeValues(paragraph, currentRun, currentText, runIndex, map);
|
||||
currentText = "";
|
||||
isfinde = false;
|
||||
}
|
||||
} else if (text.indexOf("{") >= 0) {// 判断是不是开始
|
||||
currentText = text;
|
||||
isfinde = true;
|
||||
currentRun = run;
|
||||
} else {
|
||||
currentText = "";
|
||||
}
|
||||
if (currentText.indexOf("}}") != -1) {
|
||||
changeValues(paragraph, currentRun, currentText, runIndex, map);
|
||||
isfinde = false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void parseThisRow(List<XWPFTableCell> cells, Map<String, Object> map) throws Exception {
|
||||
for (XWPFTableCell cell : cells) {
|
||||
parseAllParagraphic(cell.getParagraphs(), map);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析这个段落
|
||||
*
|
||||
* @param table
|
||||
* @param map
|
||||
* @throws Exception
|
||||
*/
|
||||
private void parseThisTable(XWPFTable table, Map<String, Object> map) throws Exception {
|
||||
XWPFTableRow row;
|
||||
List<XWPFTableCell> cells;
|
||||
Object listobj;
|
||||
ExcelEntityParse excelEntityParse = new ExcelEntityParse();
|
||||
for (int i = 0; i < table.getNumberOfRows(); i++) {
|
||||
row = table.getRow(i);
|
||||
cells = row.getTableCells();
|
||||
if (cells.size() == 1) {
|
||||
listobj = checkThisTableIsNeedIterator(cells.get(0), map);
|
||||
if (listobj == null) {
|
||||
parseThisRow(cells, map);
|
||||
} else if (listobj instanceof ExcelListEntity) {
|
||||
table.removeRow(i);// 删除这一行
|
||||
excelEntityParse.parseNextRowAndAddRow(table, i, (ExcelListEntity) listobj);
|
||||
} else {
|
||||
table.removeRow(i);// 删除这一行
|
||||
ExcelMapParse.parseNextRowAndAddRow(table, i, (List) listobj);
|
||||
}
|
||||
} else {
|
||||
parseThisRow(cells, map);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析07版的Word并且进行赋值
|
||||
* @param url
|
||||
* @param map
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public XWPFDocument parseWord(String url, Map<String, Object> map) throws Exception {
|
||||
MyXWPFDocument doc = WordCache.getXWPFDocumen(url);
|
||||
parseWordSetValue(doc, map);
|
||||
return doc;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析07版的Word并且进行赋值
|
||||
*
|
||||
* @param document
|
||||
* @param map
|
||||
* @throws Exception
|
||||
*/
|
||||
public void parseWord(XWPFDocument document, Map<String, Object> map) throws Exception {
|
||||
parseWordSetValue((MyXWPFDocument) document, map);
|
||||
}
|
||||
|
||||
private void parseWordSetValue(MyXWPFDocument doc, Map<String, Object> map) throws Exception {
|
||||
// 第一步解析文档
|
||||
parseAllParagraphic(doc.getParagraphs(), map);
|
||||
// 第二步解析页眉,页脚
|
||||
parseHeaderAndFoot(doc, map);
|
||||
// 第三步解析所有表格
|
||||
XWPFTable table;
|
||||
Iterator<XWPFTable> itTable = doc.getTablesIterator();
|
||||
while (itTable.hasNext()) {
|
||||
table = itTable.next();
|
||||
if (table.getText().indexOf("{{") != -1) {
|
||||
parseThisTable(table, map);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析页眉和页脚
|
||||
*
|
||||
* @param doc
|
||||
* @param map
|
||||
* @throws Exception
|
||||
*/
|
||||
private void parseHeaderAndFoot(MyXWPFDocument doc, Map<String, Object> map) throws Exception {
|
||||
List<XWPFHeader> headerList = doc.getHeaderList();
|
||||
for (XWPFHeader xwpfHeader : headerList) {
|
||||
for (int i = 0; i < xwpfHeader.getListParagraph().size(); i++) {
|
||||
parseThisParagraph(xwpfHeader.getListParagraph().get(i), map);
|
||||
}
|
||||
}
|
||||
List<XWPFFooter> footerList = doc.getFooterList();
|
||||
for (XWPFFooter xwpfFooter : footerList) {
|
||||
for (int i = 0; i < xwpfFooter.getListParagraph().size(); i++) {
|
||||
parseThisParagraph(xwpfFooter.getListParagraph().get(i), map);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+217
@@ -0,0 +1,217 @@
|
||||
package com.pig4cloud.pigx.common.poi.word.parse.excel;
|
||||
|
||||
import com.pig4cloud.pigx.common.poi.excel.annotation.ExcelTarget;
|
||||
import com.pig4cloud.pigx.common.poi.excel.entity.params.ExcelExportEntity;
|
||||
import com.pig4cloud.pigx.common.poi.excel.export.base.ExportBase;
|
||||
import com.pig4cloud.pigx.common.poi.exception.word.WordExportException;
|
||||
import com.pig4cloud.pigx.common.poi.exception.word.enmus.WordExportEnum;
|
||||
import com.pig4cloud.pigx.common.poi.util.PoiPublicUtil;
|
||||
import com.pig4cloud.pigx.common.poi.word.entity.params.ExcelListEntity;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.poi.xwpf.usermodel.XWPFTable;
|
||||
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
|
||||
import org.apache.poi.xwpf.usermodel.XWPFTableRow;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* 解析实体类对象 复用注解
|
||||
*
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
*/
|
||||
@Slf4j
|
||||
public class ExcelEntityParse extends ExportBase {
|
||||
|
||||
private static void checkExcelParams(ExcelListEntity entity) {
|
||||
if (entity.getList() == null || entity.getClazz() == null) {
|
||||
throw new WordExportException(WordExportEnum.EXCEL_PARAMS_ERROR);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* createCells
|
||||
*
|
||||
* @param index
|
||||
* @param t
|
||||
* @param excelParams
|
||||
* @param table
|
||||
* @param rowHeight
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
private int createCells(int index, Object t, List<ExcelExportEntity> excelParams, XWPFTable table, short rowHeight) throws Exception {
|
||||
ExcelExportEntity entity;
|
||||
XWPFTableRow row = table.createRow();
|
||||
row.setHeight(rowHeight);
|
||||
int maxHeight = 1, cellNum = 0;
|
||||
for (int k = 0, paramSize = excelParams.size(); k < paramSize; k++) {
|
||||
entity = excelParams.get(k);
|
||||
if (entity.getList() != null) {
|
||||
Collection<?> list = (Collection<?>) entity.getMethod().invoke(t, new Object[] {});
|
||||
int listC = 0;
|
||||
for (Object obj : list) {
|
||||
createListCells(index + listC, cellNum, obj, entity.getList(), table);
|
||||
listC++;
|
||||
}
|
||||
cellNum += entity.getList().size();
|
||||
if (list != null && list.size() > maxHeight) {
|
||||
maxHeight = list.size();
|
||||
}
|
||||
} else {
|
||||
Object value = getCellValue(entity, t);
|
||||
if (entity.getType() == 1) {
|
||||
setCellValue(row, value, cellNum++);
|
||||
}
|
||||
}
|
||||
}
|
||||
// 合并需要合并的单元格
|
||||
cellNum = 0;
|
||||
for (int k = 0, paramSize = excelParams.size(); k < paramSize; k++) {
|
||||
entity = excelParams.get(k);
|
||||
if (entity.getList() != null) {
|
||||
cellNum += entity.getList().size();
|
||||
} else if (entity.isNeedMerge()) {
|
||||
table.setCellMargins(index, index + maxHeight - 1, cellNum, cellNum);
|
||||
cellNum++;
|
||||
}
|
||||
}
|
||||
return maxHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建List之后的各个Cells
|
||||
*
|
||||
* @param index
|
||||
* @param cellNum
|
||||
* @param obj
|
||||
* @param excelParams
|
||||
* @param table
|
||||
* @throws Exception
|
||||
*/
|
||||
public void createListCells(int index, int cellNum, Object obj, List<ExcelExportEntity> excelParams, XWPFTable table) throws Exception {
|
||||
ExcelExportEntity entity;
|
||||
XWPFTableRow row;
|
||||
if (table.getRow(index) == null) {
|
||||
row = table.createRow();
|
||||
row.setHeight(getRowHeight(excelParams));
|
||||
} else {
|
||||
row = table.getRow(index);
|
||||
}
|
||||
for (int k = 0, paramSize = excelParams.size(); k < paramSize; k++) {
|
||||
entity = excelParams.get(k);
|
||||
Object value = getCellValue(entity, obj);
|
||||
if (entity.getType() == 1) {
|
||||
setCellValue(row, value, cellNum++);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取表头数据
|
||||
*
|
||||
* @param table
|
||||
* @param index
|
||||
* @return
|
||||
*/
|
||||
private Map<String, Integer> getTitleMap(XWPFTable table, int index, int headRows) {
|
||||
if (index < headRows) {
|
||||
throw new WordExportException(WordExportEnum.EXCEL_NO_HEAD);
|
||||
}
|
||||
Map<String, Integer> map = new HashMap<String, Integer>();
|
||||
String text;
|
||||
for (int j = 0; j < headRows; j++) {
|
||||
List<XWPFTableCell> cells = table.getRow(index - j - 1).getTableCells();
|
||||
for (int i = 0; i < cells.size(); i++) {
|
||||
text = cells.get(i).getText();
|
||||
if (StringUtils.isEmpty(text)) {
|
||||
throw new WordExportException(WordExportEnum.EXCEL_HEAD_HAVA_NULL);
|
||||
}
|
||||
map.put(text, i);
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析上一行并生成更多行
|
||||
*
|
||||
* @param table
|
||||
* @param index
|
||||
* @param entity
|
||||
*/
|
||||
public void parseNextRowAndAddRow(XWPFTable table, int index, ExcelListEntity entity) {
|
||||
checkExcelParams(entity);
|
||||
// 获取表头数据
|
||||
Map<String, Integer> titlemap = getTitleMap(table, index, entity.getHeadRows());
|
||||
try {
|
||||
// 得到所有字段
|
||||
Field fileds[] = PoiPublicUtil.getClassFields(entity.getClazz());
|
||||
ExcelTarget etarget = entity.getClazz().getAnnotation(ExcelTarget.class);
|
||||
String targetId = null;
|
||||
if (etarget != null) {
|
||||
targetId = etarget.value();
|
||||
}
|
||||
// 获取实体对象的导出数据
|
||||
List<ExcelExportEntity> excelParams = new ArrayList<ExcelExportEntity>();
|
||||
getAllExcelField(null, targetId, fileds, excelParams, entity.getClazz(), null);
|
||||
// 根据表头进行筛选排序
|
||||
sortAndFilterExportField(excelParams, titlemap);
|
||||
short rowHeight = getRowHeight(excelParams);
|
||||
Iterator<?> its = entity.getList().iterator();
|
||||
while (its.hasNext()) {
|
||||
Object t = its.next();
|
||||
index += createCells(index, t, excelParams, table, rowHeight);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* setCellValue
|
||||
*
|
||||
* @param row
|
||||
* @param value
|
||||
* @param cellNum
|
||||
*/
|
||||
private void setCellValue(XWPFTableRow row, Object value, int cellNum) {
|
||||
if (row.getCell(cellNum++) != null) {
|
||||
row.getCell(cellNum - 1).setText(value == null ? "" : value.toString());
|
||||
} else {
|
||||
row.createCell().setText(value == null ? "" : value.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 对导出序列进行排序和塞选
|
||||
*
|
||||
* @param excelParams
|
||||
* @param titlemap
|
||||
* @return
|
||||
*/
|
||||
private void sortAndFilterExportField(List<ExcelExportEntity> excelParams, Map<String, Integer> titlemap) {
|
||||
for (int i = excelParams.size() - 1; i >= 0; i--) {
|
||||
if (excelParams.get(i).getList() != null && excelParams.get(i).getList().size() > 0) {
|
||||
sortAndFilterExportField(excelParams.get(i).getList(), titlemap);
|
||||
if (excelParams.get(i).getList().size() == 0) {
|
||||
excelParams.remove(i);
|
||||
} else {
|
||||
excelParams.get(i).setOrderNum(i);
|
||||
}
|
||||
} else {
|
||||
if (titlemap.containsKey(excelParams.get(i).getName())) {
|
||||
excelParams.get(i).setOrderNum(i);
|
||||
} else {
|
||||
excelParams.remove(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
sortAllParams(excelParams);
|
||||
}
|
||||
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
package com.pig4cloud.pigx.common.poi.word.parse.excel;
|
||||
|
||||
import org.apache.poi.xwpf.usermodel.XWPFTable;
|
||||
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
|
||||
import org.apache.poi.xwpf.usermodel.XWPFTableRow;
|
||||
import com.pig4cloud.pigx.common.poi.util.PoiPublicUtil;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 处理和生成Map 类型的数据变成表格
|
||||
*
|
||||
* @author: Luckly
|
||||
* @date: 2019-05-20
|
||||
* <p>
|
||||
*/
|
||||
public final class ExcelMapParse {
|
||||
|
||||
/**
|
||||
* 解析参数行,获取参数列表
|
||||
*
|
||||
* @param currentRow
|
||||
* @return
|
||||
*/
|
||||
private static String[] parseCurrentRowGetParams(XWPFTableRow currentRow) {
|
||||
List<XWPFTableCell> cells = currentRow.getTableCells();
|
||||
String[] params = new String[cells.size()];
|
||||
String text;
|
||||
for (int i = 0; i < cells.size(); i++) {
|
||||
text = cells.get(i).getText();
|
||||
params[i] = text == null ? "" : text.trim().replace("{{", "").replace("}}", "");
|
||||
}
|
||||
return params;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析下一行,并且生成更多的行
|
||||
*
|
||||
* @param table
|
||||
* @param index
|
||||
* @param list
|
||||
* @throws Exception
|
||||
*/
|
||||
public static void parseNextRowAndAddRow(XWPFTable table, int index, List<Object> list) throws Exception {
|
||||
XWPFTableRow currentRow = table.getRow(index);
|
||||
String[] params = parseCurrentRowGetParams(currentRow);
|
||||
table.removeRow(index);// 移除这一行
|
||||
int cellIndex = 0;// 创建完成对象一行好像多了一个cell
|
||||
for (Object obj : list) {
|
||||
currentRow = table.createRow();
|
||||
for (cellIndex = 0; cellIndex < currentRow.getTableCells().size(); cellIndex++) {
|
||||
currentRow.getTableCells().get(cellIndex).setText(PoiPublicUtil.getValueDoWhile(obj, params[cellIndex].split("\\."), 0).toString());
|
||||
}
|
||||
for (; cellIndex < params.length; cellIndex++) {
|
||||
currentRow.createCell().setText(PoiPublicUtil.getValueDoWhile(obj, params[cellIndex].split("\\."), 0).toString());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -27,6 +27,11 @@
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<!--pigx 工具包-->
|
||||
<dependency>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common-autopoi</artifactId>
|
||||
<version>${pigx.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.pig4cloud</groupId>
|
||||
<artifactId>pigx-common-core</artifactId>
|
||||
|
||||
@@ -43,5 +43,6 @@
|
||||
<module>pigx-common-security</module>
|
||||
<module>pigx-common-swagger</module>
|
||||
<module>pigx-common-transaction</module>
|
||||
<module>pigx-common-autopoi</module>
|
||||
</modules>
|
||||
</project>
|
||||
@@ -56,6 +56,7 @@
|
||||
<curator.version>2.10.0</curator.version>
|
||||
<velocity.version>1.7</velocity.version>
|
||||
<lcn.version>4.1.0</lcn.version>
|
||||
<poi.version>3.15</poi.version>
|
||||
<jasypt.version>2.1.1</jasypt.version>
|
||||
<ttl.version>2.10.2</ttl.version>
|
||||
<minio.version>6.0.4</minio.version>
|
||||
@@ -124,6 +125,23 @@
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<!-- poi begin https://gitee.com/lemur/easypoi/issues/INTGY-->
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi</artifactId>
|
||||
<version>${poi.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi-ooxml</artifactId>
|
||||
<version>${poi.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi-ooxml-schemas</artifactId>
|
||||
<version>${poi.version}</version>
|
||||
</dependency>
|
||||
<!-- poi end-->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-dependencies</artifactId>
|
||||
|
||||
Reference in new issue
Block a user