This commit is contained in:
ls
2025-02-23 12:03:06 +08:00
parent d69092f729
commit a5697c2ba8
130 changed files with 16414 additions and 0 deletions

10
autopoi/.gitignore vendored Normal file
View File

@@ -0,0 +1,10 @@
## ide
**/.idea
*.iml
## backend
**/target
**/logs
## front
**/*.lock

191
autopoi/LICENSE Normal file
View File

@@ -0,0 +1,191 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction, and
distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by the copyright
owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all other entities
that control, are controlled by, or are under common control with that entity.
For the purposes of this definition, "control" means (i) the power, direct or
indirect, to cause the direction or management of such entity, whether by
contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity exercising
permissions granted by this License.
"Source" form shall mean the preferred form for making modifications, including
but not limited to software source code, documentation source, and configuration
files.
"Object" form shall mean any form resulting from mechanical transformation or
translation of a Source form, including but not limited to compiled object code,
generated documentation, and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or Object form, made
available under the License, as indicated by a copyright notice that is included
in or attached to the work (an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object form, that
is based on (or derived from) the Work and for which the editorial revisions,
annotations, elaborations, or other modifications represent, as a whole, an
original work of authorship. For the purposes of this License, Derivative Works
shall not include works that remain separable from, or merely link (or bind by
name) to the interfaces of, the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including the original version
of the Work and any modifications or additions to that Work or Derivative Works
thereof, that is intentionally submitted to Licensor for inclusion in the Work
by the copyright owner or by an individual or Legal Entity authorized to submit
on behalf of the copyright owner. For the purposes of this definition,
"submitted" means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems, and
issue tracking systems that are managed by, or on behalf of, the Licensor for
the purpose of discussing and improving the Work, but excluding communication
that is conspicuously marked or otherwise designated in writing by the copyright
owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf
of whom a Contribution has been received by Licensor and subsequently
incorporated within the Work.
2. Grant of Copyright License.
Subject to the terms and conditions of this License, each Contributor hereby
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
irrevocable copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the Work and such
Derivative Works in Source or Object form.
3. Grant of Patent License.
Subject to the terms and conditions of this License, each Contributor hereby
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
irrevocable (except as stated in this section) patent license to make, have
made, use, offer to sell, sell, import, and otherwise transfer the Work, where
such license applies only to those patent claims licensable by such Contributor
that are necessarily infringed by their Contribution(s) alone or by combination
of their Contribution(s) with the Work to which such Contribution(s) was
submitted. If You institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work or a
Contribution incorporated within the Work constitutes direct or contributory
patent infringement, then any patent licenses granted to You under this License
for that Work shall terminate as of the date such litigation is filed.
4. Redistribution.
You may reproduce and distribute copies of the Work or Derivative Works thereof
in any medium, with or without modifications, and in Source or Object form,
provided that You meet the following conditions:
You must give any other recipients of the Work or Derivative Works a copy of
this License; and
You must cause any modified files to carry prominent notices stating that You
changed the files; and
You must retain, in the Source form of any Derivative Works that You distribute,
all copyright, patent, trademark, and attribution notices from the Source form
of the Work, excluding those notices that do not pertain to any part of the
Derivative Works; and
If the Work includes a "NOTICE" text file as part of its distribution, then any
Derivative Works that You distribute must include a readable copy of the
attribution notices contained within such NOTICE file, excluding those notices
that do not pertain to any part of the Derivative Works, in at least one of the
following places: within a NOTICE text file distributed as part of the
Derivative Works; within the Source form or documentation, if provided along
with the Derivative Works; or, within a display generated by the Derivative
Works, if and wherever such third-party notices normally appear. The contents of
the NOTICE file are for informational purposes only and do not modify the
License. You may add Your own attribution notices within Derivative Works that
You distribute, alongside or as an addendum to the NOTICE text from the Work,
provided that such additional attribution notices cannot be construed as
modifying the License.
You may add Your own copyright statement to Your modifications and may provide
additional or different license terms and conditions for use, reproduction, or
distribution of Your modifications, or for any such Derivative Works as a whole,
provided Your use, reproduction, and distribution of the Work otherwise complies
with the conditions stated in this License.
5. Submission of Contributions.
Unless You explicitly state otherwise, any Contribution intentionally submitted
for inclusion in the Work by You to the Licensor shall be under the terms and
conditions of this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify the terms of
any separate license agreement you may have executed with Licensor regarding
such Contributions.
6. Trademarks.
This License does not grant permission to use the trade names, trademarks,
service marks, or product names of the Licensor, except as required for
reasonable and customary use in describing the origin of the Work and
reproducing the content of the NOTICE file.
7. Disclaimer of Warranty.
Unless required by applicable law or agreed to in writing, Licensor provides the
Work (and each Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
including, without limitation, any warranties or conditions of TITLE,
NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
solely responsible for determining the appropriateness of using or
redistributing the Work and assume any risks associated with Your exercise of
permissions under this License.
8. Limitation of Liability.
In no event and under no legal theory, whether in tort (including negligence),
contract, or otherwise, unless required by applicable law (such as deliberate
and grossly negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special, incidental,
or consequential damages of any character arising as a result of this License or
out of the use or inability to use the Work (including but not limited to
damages for loss of goodwill, work stoppage, computer failure or malfunction, or
any and all other commercial damages or losses), even if such Contributor has
been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability.
While redistributing the Work or Derivative Works thereof, You may choose to
offer, and charge a fee for, acceptance of support, warranty, indemnity, or
other liability obligations and/or rights consistent with this License. However,
in accepting such obligations, You may act only on Your own behalf and on Your
sole responsibility, not on behalf of any other Contributor, and only if You
agree to indemnify, defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason of your
accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work
To apply the Apache License to your work, attach the following boilerplate
notice, with the fields enclosed by brackets "{}" replaced with your own
identifying information. (Don't include the brackets!) The text should be
enclosed in the appropriate comment syntax for the file format. We also
recommend that a file or class name and description of purpose be included on
the same "printed page" as the copyright notice for easier identification within
third-party archives.
Copyright 2019 scott
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -0,0 +1,43 @@
<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">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.jeecgframework.boot3</groupId>
<artifactId>autopoi-parent</artifactId>
<version>3.7.0</version>
</parent>
<artifactId>autopoi-web</artifactId>
<dependencies>
<!-- autopoi -->
<dependency>
<groupId>org.jeecgframework.boot3</groupId>
<artifactId>autopoi</artifactId>
<version>${autopoi.version}</version>
</dependency>
<!--spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<optional>true</optional>
</dependency>
<!-- servlet -->
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>6.0.0</version>
<scope>provided</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-to-slf4j</artifactId>
<version>2.11.2</version>
<optional>true</optional>
<scope>test</scope>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,39 @@
/**
* Copyright 2013-2015 JEECG (jeecgos@163.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jeecgframework.poi.excel.def;
/**
* 基础POI常量
*
* @author JEECG
* @date 2014年6月30日 下午9:23:37
*/
interface BasePOIConstants {
/**
* 注解对象
*/
public final static String CLASS = "entity";
/**
* 表格参数
*/
public final static String PARAMS = "params";
/**
* 下载文件名称
*/
public final static String FILE_NAME = "fileName";
}

View File

@@ -0,0 +1,37 @@
/**
* Copyright 2013-2015 JEECG (jeecgos@163.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jeecgframework.poi.excel.def;
/**
* 正常导出Excel
*
* @Author JEECG on 14-3-8. 静态常量
*/
public interface MapExcelConstants extends BasePOIConstants {
/**
* 单Sheet导出
*/
public final static String JEECG_MAP_EXCEL_VIEW = "jeecgMapExcelView";
/**
* Entity List
*/
public final static String ENTITY_LIST = "data";
/**
* 数据列表
*/
public final static String MAP_LIST = "mapList";
}

View File

@@ -0,0 +1,43 @@
/**
* Copyright 2013-2015 JEECG (jeecgos@163.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jeecgframework.poi.excel.def;
/**
* 正常导出Excel
*
* @Author JEECG on 14-3-8. 静态常量
*/
public interface NormalExcelConstants extends BasePOIConstants {
/**
* 单Sheet导出
*/
public final static String JEECG_ENTITY_EXCEL_VIEW = "jeecgEntityExcelView";
/**
* 数据列表
*/
public final static String DATA_LIST = "data";
/**
* 多Sheet 对象
*/
public final static String MAP_LIST = "mapList";
/**
* 导出字段自定义
*/
public final static String EXPORT_FIELDS = "exportFields";
}

View File

@@ -0,0 +1,38 @@
/**
* Copyright 2013-2015 JEECG (jeecgos@163.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jeecgframework.poi.excel.def;
/**
* 模板Excel导出常量
*
* @author JEECG
* @date 2014年6月30日 下午9:26:52
*/
public interface TemplateExcelConstants extends BasePOIConstants {
/**
* 模板导出
*/
public final static String JEECG_TEMPLATE_EXCEL_VIEW = "jeecgTemplateExcelView";
/**
* 数据列表
*/
public final static String LIST_DATA = "list";
/**
* 模板参数
*/
public final static String MAP_DATA = "map";
}

View File

@@ -0,0 +1,38 @@
/**
* Copyright 2013-2015 JEECG (jeecgos@163.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jeecgframework.poi.excel.def;
/**
* Word 导出模板常量
*
* @author JEECG
* @date 2014年7月24日 下午11:26:46
*/
public interface TemplateWordConstants extends BasePOIConstants {
/**
* 模板导出
*/
public final static String JEECG_TEMPLATE_WORD_VIEW = "jeecgTemplateWordView";
/**
* 数据列表
*/
public final static String URL = "url";
/**
* 模板参数
*/
public final static String MAP_DATA = "map";
}

View File

@@ -0,0 +1,89 @@
/**
* Copyright 2013-2015 JEECG (jeecgos@163.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jeecgframework.poi.excel.view;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Workbook;
import org.jeecgframework.poi.excel.ExcelExportUtil;
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
import org.jeecgframework.poi.excel.entity.ExportParams;
import org.jeecgframework.poi.excel.export.ExcelExportServer;
import org.springframework.stereotype.Controller;
/**
* Entity 实体数据对象导出
* @Author JEECG
*
*/
@SuppressWarnings("unchecked")
@Controller(NormalExcelConstants.JEECG_ENTITY_EXCEL_VIEW)
public class JeecgEntityExcelView extends MiniAbstractExcelView {
public JeecgEntityExcelView() {
super();
}
@Override
protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
String codedFileName = "临时文件";
Workbook workbook = null;
//---update-end-----autor:scott------date:20191016-------for:导出字段支持自定义--------
String[] exportFields = null;
Object exportFieldStr = model.get(NormalExcelConstants.EXPORT_FIELDS);
if(exportFieldStr!=null && exportFieldStr!=""){
exportFields = exportFieldStr.toString().split(",");
}
//---update-end-----autor:scott------date:20191016-------for:导出字段支持自定义--------
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),exportFields);
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),exportFields);
}
} else {
workbook = ExcelExportUtil.exportExcel((ExportParams) model.get(NormalExcelConstants.PARAMS), (Class<?>) model.get(NormalExcelConstants.CLASS), (Collection<?>) model.get(NormalExcelConstants.DATA_LIST),exportFields);
}
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();
}
}

View File

@@ -0,0 +1,71 @@
/**
* Copyright 2013-2015 JEECG (jeecgos@163.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jeecgframework.poi.excel.view;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Workbook;
import org.jeecgframework.poi.excel.ExcelExportUtil;
import org.jeecgframework.poi.excel.def.MapExcelConstants;
import org.jeecgframework.poi.excel.entity.ExportParams;
import org.jeecgframework.poi.excel.entity.params.ExcelExportEntity;
import org.springframework.stereotype.Controller;
/**
* Map 数据对象接口导出
*
* @author JEECG
* @date 2014年11月25日 下午3:26:32
*/
@SuppressWarnings("unchecked")
@Controller(MapExcelConstants.JEECG_MAP_EXCEL_VIEW)
public class JeecgMapExcelView extends MiniAbstractExcelView {
public JeecgMapExcelView() {
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();
}
}

View File

@@ -0,0 +1,69 @@
/**
* Copyright 2013-2015 JEECG (jeecgos@163.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jeecgframework.poi.excel.view;
import java.util.List;
import java.util.Map;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Workbook;
import org.jeecgframework.poi.excel.ExcelExportUtil;
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
import org.jeecgframework.poi.excel.def.TemplateExcelConstants;
import org.jeecgframework.poi.excel.entity.TemplateExportParams;
import org.springframework.stereotype.Controller;
/**
* Excel 模板导出
*
* @author JEECG
* @date 2014年6月30日 下午9:15:49
*/
@SuppressWarnings("unchecked")
@Controller(TemplateExcelConstants.JEECG_TEMPLATE_EXCEL_VIEW)
public class JeecgTemplateExcelView extends MiniAbstractExcelView {
public JeecgTemplateExcelView() {
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();
}
}

View File

@@ -0,0 +1,67 @@
/**
* Copyright 2013-2015 JEECG (jeecgos@163.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jeecgframework.poi.excel.view;
import java.util.Map;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.jeecgframework.poi.excel.def.TemplateWordConstants;
import org.jeecgframework.poi.word.WordExportUtil;
import org.springframework.stereotype.Controller;
import org.springframework.web.servlet.view.AbstractView;
/**
* Word模板导出
*
* @author JEECG
* @date 2014年6月30日 下午9:15:49
*/
@SuppressWarnings("unchecked")
@Controller(TemplateWordConstants.JEECG_TEMPLATE_WORD_VIEW)
public class JeecgTemplateWordView extends AbstractView {
private static final String CONTENT_TYPE = "application/msword";
public JeecgTemplateWordView() {
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();
}
}

View File

@@ -0,0 +1,43 @@
/**
* Copyright 2013-2015 JEECG (jeecgos@163.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jeecgframework.poi.excel.view;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.web.servlet.view.AbstractView;
/**
* 基础抽象Excel View
*
* @author JEECG
* @date 2015年2月28日 下午1:41:05
*/
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;
}
}

View File

@@ -0,0 +1,80 @@
import org.apache.poi.ss.usermodel.Workbook;
import org.jeecgframework.poi.excel.ExcelExportUtil;
import org.jeecgframework.poi.excel.entity.ExportParams;
import org.jeecgframework.poi.handler.inter.IExcelExportServer;
import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* @Description: 大数据导出示例
* @author: liusq
* @date: 2022年1月4日
*/
public class DaoChuBigDataTest {
/**
* 导出测试方法
* 参考http://doc.wupaas.com/docs/easypoi/easypoi-1c10lbsojh62f
* 参考https://blog.csdn.net/weixin_45214729/article/details/118552415
* @author liusq
* @date: 2022年1月4日
* @throws Exception
*/
public static void bigDataExport() throws Exception {
Workbook workbook = null;
List<TestEntity> aList = new ArrayList<TestEntity>();
ExportParams exportParams = new ExportParams();
Date start = new Date();
//模拟100w数据
for(int j=0;j<1000000;j++){
TestEntity testEntity = new TestEntity();
testEntity.setName("李四"+j);
testEntity.setAge(j);
aList.add(testEntity);
}
//分别是 totalPage是总页数pageSize 页码长度
int totalPage = (aList.size() / 100000) + 1;
int pageSize = 100000;
/**
* params:表格标题属性筛选条件sheet值
* TestEntity表格的实体类
*/
workbook = ExcelExportUtil.exportBigExcel(exportParams,TestEntity.class, new IExcelExportServer() {
/**
* obj 就是下面的totalPage限制条件
* page 是页数他是在分页进行文件转换page每次+1
*/
@Override
public List<Object> selectListForExcelExport(Object obj, int page) {
//很重要这里面整个方法体其实就是将所有的数据aList分批返回处理
//分批的方式很多我直接用了subList。然后 每批不能太大。我试了30000一批
//特别注意最好每次10000条否则可能有内存溢出风险
if (page > totalPage) {
return null;
}
// fromIndex开始索引toIndex结束索引
int fromIndex = (page - 1) * pageSize;
int toIndex = page != totalPage ? fromIndex + pageSize :aList.size();
//不是空时一直循环运行selectListForExcelExport。每次返回1万条数据。
List<Object> list = new ArrayList<>();
list.addAll(aList.subList(fromIndex, toIndex));
return list;
}
}, totalPage);
File savefile = new File("D:/excel/");
if (!savefile.exists()) {
savefile.mkdirs();
}
FileOutputStream fos = new FileOutputStream("D:/excel/ExcelExportBigData.bigDataExport.xlsx");
workbook.write(fos);
fos.close();
System.out.println("耗时(秒)"+((new Date().getTime() - start.getTime())/ 1000));
}
public static void main(String[] args) throws Exception {
bigDataExport();
}
}

View File

@@ -0,0 +1,69 @@
import org.apache.poi.ss.usermodel.Workbook;
import org.jeecgframework.poi.excel.ExcelExportUtil;
import org.jeecgframework.poi.excel.entity.ExportParams;
import org.jeecgframework.poi.excel.entity.TemplateExportParams;
import org.jeecgframework.poi.excel.entity.enmus.ExcelType;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @Description: 参考文档http://doc.jeecg.com/2044223
* @author: scott
* @date: 2020年09月16日 11:46
*/
public class DaoChuSheetTest {
private static final String basePath = "G:\\needtodeplay\\autopoi-framework-sy-4.0\\autopoi-web\\src\\test\\resources\\templates\\";
public static ExportParams getExportParams(String name) {
return new ExportParams(name,name,ExcelType.XSSF);
}
public static Workbook test() {
/**
* 多个Map
* title:对应表格Title
* entity对应表格对应实体
* dataCollection 数据
*/
List<Map<String, Object>> listMap = new ArrayList<Map<String, Object>>();
for(int i=0;i<3;i++){
Map<String, Object> map = new HashMap<String, Object>();
map.put("title", getExportParams("测试"+i));//表格Title
map.put("entity",TestEntity.class);//表格对应实体
List<TestEntity> ls=new ArrayList<TestEntity> ();
for(int j=0;j<10;j++){
TestEntity testEntity = new TestEntity();
testEntity.setName("张三"+i+j);
testEntity.setAge(18+i+j);
ls.add(testEntity);
}
List<Map> ls2=new ArrayList<Map> ();
for(int j=0;j<10;j++){
Map map1 = new HashMap();
map1.put("name","李四"+i+j);
map1.put("age",18+i+j);
ls2.add(map1);
}
map.put("data", ls);//ls or ls2
listMap.add(map);
}
Workbook workbook = ExcelExportUtil.exportExcel(listMap, ExcelType.XSSF);
return workbook;
}
public static void main(String[] args) throws IOException {
Workbook workbook = test();
File savefile = new File(basePath);
if (!savefile.exists()) {
savefile.mkdirs();
}
FileOutputStream fos = new FileOutputStream(basePath + "testSheet.xlsx");
workbook.write(fos);
fos.close();
}
}

View File

@@ -0,0 +1,55 @@
import org.apache.poi.ss.usermodel.Workbook;
import org.jeecgframework.poi.excel.ExcelExportUtil;
import org.jeecgframework.poi.excel.entity.TemplateExportParams;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @Description: TODO
* @author: scott
* @date: 2020年09月16日 11:46
*/
public class DaoChuTest {
private static final String basePath = "G:\\needtodeplay\\autopoi-framework-sy-4.0\\autopoi-web\\src\\test\\resources\\templates\\";
public static TemplateExportParams getTemplateParams(String name) {
return new TemplateExportParams(basePath + name + ".xlsx");
}
public static Workbook test(String name) {
TemplateExportParams params = getTemplateParams(name);
Map<String, Object> map = new HashMap<String, Object>();
List<Map<String, Object>> listMap = new ArrayList<Map<String, Object>>();
for (int i = 0; i < 3; i++) {
Map<String, Object> lm = new HashMap<String, Object>();
lm.put("name", "姓名1" + i);
lm.put("isTts", i);
lm.put("sname", "s姓名");
lm.put("ttsContent", "ttsContent内容");
lm.put("rate", 1000 + i);
listMap.add(lm);
}
map.put("autoList", listMap);
Workbook workbook = ExcelExportUtil.exportExcel(params, map);
return workbook;
}
public static void main(String[] args) throws IOException {
String temName = "test";
String temNameNextM = "testNextMarge";
Workbook workbook = test(temNameNextM);
File savefile = new File(basePath);
if (!savefile.exists()) {
savefile.mkdirs();
}
FileOutputStream fos = new FileOutputStream(basePath + "testNew.xlsx");
workbook.write(fos);
fos.close();
}
}

View File

@@ -0,0 +1,57 @@
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.jeecgframework.poi.word.WordExportUtil;
import java.io.File;
import java.io.FileOutputStream;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* @Description: TODO
* @author: scott
* @date: 2020年09月16日 11:46
*/
public class DaoChuWordTest {
private static final String basePath = "G:\\needtodeplay\\autopoi-framework-sy-4.0\\autopoi-web\\src\\test\\resources\\templates\\";
public static void main(String[] args) throws Exception {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String curTime = format.format(new Date());
Map<String, Object> map = new HashMap<String, Object>();
List<Map<String, Object>> mapList = new ArrayList<Map<String, Object>>();
// Map<String, Object> map1 = new HashMap<String, Object>();
// map1.put("type", "个人所得税");
// map1.put("presum", "1580");
// map1.put("thissum", "1750");
// map1.put("curmonth", "1-11月");
// map1.put("now", curTime);
// mapList.add(map1);
// Map<String, Object> map2 = new HashMap<String, Object>();
// map2.put("type", "增值税");
// map2.put("presum", "1080");
// map2.put("thissum", "1650");
// map2.put("curmonth", "1-11月");
// map2.put("now", curTime);
// mapList.add(map2);
map.put("taxlist", mapList);
map.put("totalpreyear", "2660");
map.put("totalthisyear", "3400");
map.put("type", "增值税");
map.put("presum", "1080");
map.put("thissum", "1650");
map.put("curmonth", "1-11月");
map.put("now", curTime);
//单列
XWPFDocument document = WordExportUtil.exportWord07(basePath + "纳税信息.docx", map);
File savefile = new File("D:\\poi");
if (!savefile.exists()) {
savefile.mkdirs();
}
FileOutputStream fos = new FileOutputStream(basePath + "纳税信息new.docx");
document.write(fos);
fos.close();
}
}

View File

@@ -0,0 +1,29 @@
import org.jeecgframework.poi.excel.annotation.Excel;
/**
* @Description: TODO
* @author: lsq
* @date: 2021年02月02日 16:31
*/
public class TestEntity {
@Excel(name = "姓名", width = 15)
private String name;
@Excel(name = "年龄", width = 15)
private Integer age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}

73
autopoi/autopoi/pom.xml Normal file
View File

@@ -0,0 +1,73 @@
<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">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.jeecgframework.boot3</groupId>
<artifactId>autopoi-parent</artifactId>
<version>3.7.0</version>
</parent>
<artifactId>autopoi</artifactId>
<dependencies>
<!-- poi -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<exclusions>
<exclusion>
<artifactId>xml-apis</artifactId>
<groupId>xml-apis</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml-full</artifactId>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.apache.poi</groupId>-->
<!-- <artifactId>poi-ooxml-schemas</artifactId>-->
<!-- </dependency>-->
<!-- Sax 读入的时候使用 -->
<dependency>
<groupId>xerces</groupId>
<artifactId>xercesImpl</artifactId>
</dependency>
<!-- Word 时候用到 -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-scratchpad</artifactId>
</dependency>
<!-- google 工具类 -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<!--日志 -->
<!-- slf4j -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<optional>true</optional>
</dependency>
<!--spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,25 @@
package org.jeecgframework.core.util;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
/**
*
* @author 张代浩
*
*/
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;
}
}

View File

@@ -0,0 +1,23 @@
package org.jeecgframework.dict.service;
/**
* 描述:
* @authorscott
* @since2017-4-12 下午04:58:15
* @version:1.0
*/
public interface AutoPoiDictServiceI{
/**
* 方法描述: 查询数据字典
* 作 者: yiming.zhang
* 日 期: 2014年5月11日-下午4:22:42
* @param dicTable
* @param dicCode
* @param dicText
* @return
* 返回类型: List<DictEntity>
*/
public String[] queryDict(String dicTable,String dicCode, String dicText);
}

View File

@@ -0,0 +1,99 @@
/**
* Copyright 2013-2015 JEECG (jeecgos@163.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jeecgframework.poi.cache;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.jeecgframework.poi.cache.manager.POICacheManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;
/**
* Excel类型的缓存
*
* @author JEECG
* @date 2014年2月11日
* @version 1.0
*/
public final class ExcelCache {
private static final Logger LOGGER = LoggerFactory.getLogger(ExcelCache.class);
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 (Exception e) {
LOGGER.error(e.getMessage(), e);
} finally {
try {
is.close();
} catch (Exception e) {
LOGGER.error(e.getMessage(), e);
}
}
return null;
}
//update-begin-author:wangshuai date:20200730 for:jar 包上传到服务器后 autopoi 读取不到excel模版文件 #1505
public static Workbook getWorkbookByTemplate(String url, Integer[] sheetNums, boolean needAll) {
List<Integer> sheetList = Arrays.asList(sheetNums);
InputStream fis = null;
try {
//update-begin----author:liusq------date:20210129-----for:-------poi3升级到4兼容改造工作--------
//ClassPathResource resource = new ClassPathResource(url);
fis = new FileInputStream(url);
LOGGER.info(" >>> poi3升级到4兼容改造工作, url="+url);
//fis = resource.getInputStream();
//update-end-----author:liusq------date:20210129-----for:-------poi3升级到4兼容改造工作--------
Workbook wb = WorkbookFactory.create(fis);
// 删除其他的sheet
if (!needAll) {
for (int i = wb.getNumberOfSheets() - 1; i >= 0; i--) {
if (!sheetList.contains(i)) {
wb.removeSheetAt(i);
}
}
}
return wb;
} catch (Exception e) {
LOGGER.error(e.getMessage(), e);
} finally {
try {
fis.close();
} catch (Exception e) {
LOGGER.error(e.getMessage(), e);
}
}
return null;
}
//update-end-author:wangshuai date:20200730 for:jar 包上传到服务器后 autopoi 读取不到excel模版文件 #1505
}

View File

@@ -0,0 +1,99 @@
/**
* Copyright 2013-2015 JueYue (qrb.jueyue@gmail.com)
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jeecgframework.poi.cache;
import org.apache.poi.util.IOUtils;
import org.jeecgframework.poi.cache.manager.POICacheManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
/**
* 图片缓存处理
*
* @author liusq
* 2022-05-27 下午4:16:32
*/
public class ImageCache {
private static final Logger LOGGER = LoggerFactory
.getLogger(ImageCache.class);
public static byte[] getImage(String imagePath) {
InputStream is = POICacheManager.getFile(imagePath);
ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream();
final ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
try {
int ch;
while ((ch = is.read()) != -1) {
swapStream.write(ch);
}
Image image = Toolkit.getDefaultToolkit().createImage(swapStream.toByteArray());
BufferedImage bufferImg = toBufferedImage(image);
ImageIO.write(bufferImg,
imagePath.substring(imagePath.lastIndexOf(".") + 1, imagePath.length()),
byteArrayOut);
return byteArrayOut.toByteArray();
} catch (Exception e) {
LOGGER.error(e.getMessage(), e);
return null;
} finally {
IOUtils.closeQuietly(is);
IOUtils.closeQuietly(swapStream);
IOUtils.closeQuietly(byteArrayOut);
}
}
public static BufferedImage toBufferedImage(Image image) {
if (image instanceof BufferedImage) {
return (BufferedImage) image;
}
// This code ensures that all the pixels in the image are loaded
image = new ImageIcon(image).getImage();
BufferedImage bimage = null;
GraphicsEnvironment ge = GraphicsEnvironment
.getLocalGraphicsEnvironment();
try {
int transparency = Transparency.OPAQUE;
GraphicsDevice gs = ge.getDefaultScreenDevice();
GraphicsConfiguration gc = gs.getDefaultConfiguration();
bimage = gc.createCompatibleImage(image.getWidth(null),
image.getHeight(null), transparency);
} catch (HeadlessException e) {
// The system does not have a screen
}
if (bimage == null) {
// Create a buffered image using the default color model
int type = BufferedImage.TYPE_INT_RGB;
bimage = new BufferedImage(image.getWidth(null),
image.getHeight(null), type);
}
// Copy image to buffered image
Graphics g = bimage.createGraphics();
// Paint the image onto the buffered image
g.drawImage(image, 0, 0, null);
g.dispose();
return bimage;
}
}

View File

@@ -0,0 +1,53 @@
/**
* Copyright 2013-2015 JEECG (jeecgos@163.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jeecgframework.poi.cache;
import java.io.InputStream;
import org.jeecgframework.poi.cache.manager.POICacheManager;
import org.jeecgframework.poi.word.entity.MyXWPFDocument;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* word 缓存中心
*
* @author JEECG
* @date 2014年7月24日 下午10:54:31
*/
public class WordCache {
private static final Logger LOGGER = LoggerFactory.getLogger(WordCache.class);
public static MyXWPFDocument getXWPFDocumen(String url) {
InputStream is = null;
try {
is = POICacheManager.getFile(url);
MyXWPFDocument doc = new MyXWPFDocument(is);
return doc;
} catch (Exception e) {
LOGGER.error(e.getMessage(), e);
} finally {
try {
is.close();
} catch (Exception e) {
LOGGER.error(e.getMessage(), e);
}
}
return null;
}
}

View File

@@ -0,0 +1,75 @@
/**
* Copyright 2013-2015 JEECG (jeecgos@163.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jeecgframework.poi.cache.manager;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import org.jeecgframework.poi.util.PoiPublicUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 文件加载类,根据路径加载指定文件
*
* @author JEECG
* @date 2014年2月10日
* @version 1.0
*/
class FileLoade {
private static final Logger LOGGER = LoggerFactory.getLogger(FileLoade.class);
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) {
LOGGER.error(e.getMessage(), e);
} catch (IOException e) {
LOGGER.error(e.getMessage(), e);
} finally {
try {
if (fileis != null)
fileis.close();
if (fileis != null)
baos.close();
} catch (IOException e) {
LOGGER.error(e.getMessage(), e);
}
}
LOGGER.error(fileis + "这个路径文件没有找到,请查询");
return null;
}
}

View File

@@ -0,0 +1,64 @@
/**
* Copyright 2013-2015 JEECG (jeecgos@163.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jeecgframework.poi.cache.manager;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.Arrays;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
/**
* 缓存管理
*
* @author JEECG
* @date 2014年2月10日
* @version 1.0
*/
public final class POICacheManager {
private static final Logger LOGGER = LoggerFactory.getLogger(POICacheManager.class);
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) {
LOGGER.error(e.getMessage(), e);
}
return null;
}
}

View File

@@ -0,0 +1,11 @@
/**
* 对POI用到的模板进行缓存,进行统一管理,缓存工具暂时使用guava(脱离配置文件)
* 缓存方式统一为byte[] 屏蔽文件类型的差异
* 缓存获取方式,URL或者URL+index(EXcel的)
*/
/**
* @author JEECG
* @date 2014年2月10日
* @version 1.0
*/
package org.jeecgframework.poi.cache;

View File

@@ -0,0 +1,104 @@
package org.jeecgframework.poi.entity;
/**
* word导出,图片设置和图片信息
*
* @author liusq
* @date 2022-5-27
*/
public class ImageEntity {
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;
private int rowspan = 1;
private int colspan = 1;
public ImageEntity() {
}
public ImageEntity(byte[] data, int width, int height) {
this.data = data;
this.width = width;
this.height = height;
this.type = Data;
}
public ImageEntity(String url, int width, int height) {
this.url = url;
this.width = width;
this.height = height;
}
public byte[] getData() {
return data;
}
public int getHeight() {
return height;
}
public String getType() {
return type;
}
public String getUrl() {
return url;
}
public int getWidth() {
return width;
}
public void setData(byte[] data) {
this.data = data;
}
public void setHeight(int height) {
this.height = height;
}
public void setType(String type) {
this.type = type;
}
public void setUrl(String url) {
this.url = url;
}
public void setWidth(int width) {
this.width = width;
}
public int getRowspan() {
return rowspan;
}
public void setRowspan(int rowspan) {
this.rowspan = rowspan;
}
public int getColspan() {
return colspan;
}
public void setColspan(int colspan) {
this.colspan = colspan;
}
}

View File

@@ -0,0 +1,243 @@
/**
* Copyright 2013-2015 JEECG (jeecgos@163.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jeecgframework.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 org.jeecgframework.poi.excel.entity.ExportParams;
import org.jeecgframework.poi.excel.entity.TemplateExportParams;
import org.jeecgframework.poi.excel.entity.enmus.ExcelType;
import org.jeecgframework.poi.excel.entity.params.ExcelExportEntity;
import org.jeecgframework.poi.excel.export.ExcelBatchExportServer;
import org.jeecgframework.poi.excel.export.ExcelExportServer;
import org.jeecgframework.poi.excel.export.template.ExcelExportOfTemplateUtil;
import org.jeecgframework.poi.handler.inter.IExcelExportServer;
import org.jeecgframework.poi.handler.inter.IWriter;
/**
* excel 导出工具类
*
* @author JEECG
* @version 1.0
* @date 2013-10-17
*/
//update-begin---author:chenrui ---date:20231221 for[issue/#5248]加强继承扩展便利性(删除final)------------
public class ExcelExportUtil {
//update-end---author:chenrui ---date:20231221 for[issue/#5248]加强继承扩展便利性(删除final)------------
//update-begin---author:liusq Date:20211217 for[LOWCOD-2521]【autopoi】大数据导出方法【全局】----
//单sheet最大值
public static int USE_SXSSF_LIMIT = 100000;
//update-end---author:liusq Date:20211217 for[LOWCOD-2521]【autopoi】大数据导出方法【全局】----
private ExcelExportUtil() {
}
//---update-begin-----autor:scott------date:20191016-------for:导出字段支持自定义--------
/**
* 根据Entity创建对应的Excel
*
* @param entity
* 表格标题属性
* @param pojoClass
* Excel对象Class
* @param dataSet
* Excel对象数据List
* @param exportFields
* 自定义导出Excel字段数组
*/
public static Workbook exportExcel(ExportParams entity, Class<?> pojoClass, Collection<?> dataSet,String[] exportFields) {
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,exportFields);
return workbook;
}
//---update-end-----autor:scott------date:20191016-------for:导出字段支持自定义--------
/**
* 根据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,null);
return workbook;
}
/**
* 根据Map创建对应的Excel
*
* @param entity
* 表格标题属性
* @param pojoClass
* Excel对象Class
* @param dataSet
* 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, ExcelType 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"),null);
}
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);
}
//update-begin---author:liusq Date:20211227 for[LOWCOD-2521]大数据导出方法【全局】----
/**
* 大数据量导出
*
* @param entity 表格标题属性
* @param pojoClass Excel对象Class
* @date 2022年1月4号
* @return ExcelBatchExportServer 批处理服务
*/
public static IWriter<Workbook> exportBigExcel(ExportParams entity, Class<?> pojoClass) {
ExcelBatchExportServer batchServer = new ExcelBatchExportServer();
batchServer.init(entity, pojoClass);
return batchServer;
}
/**
* 大数据量导出
*
* @param entity
* @param excelParams
* @date 2022年1月4号
* @return ExcelBatchExportServer 批处理服务
*/
public static IWriter<Workbook> exportBigExcel(ExportParams entity, List<ExcelExportEntity> excelParams) {
ExcelBatchExportServer batchServer = new ExcelBatchExportServer();
batchServer.init(entity, excelParams);
return batchServer;
}
/**
* 大数据量导出
*
* @param entity 导出参数属性
* @param pojoClass Excel对象Class
* @param server 查询数据的接口
* @param queryParams 查询数据的参数
* @date 2022年1月4号
* @return Workbook
*/
public static Workbook exportBigExcel(ExportParams entity, Class<?> pojoClass,
IExcelExportServer server, Object queryParams) {
ExcelBatchExportServer batchServer = new ExcelBatchExportServer();
batchServer.init(entity, pojoClass);
return batchServer.exportBigExcel(server, queryParams);
}
/**
* 大数据量导出
* @param entity
* @param excelParams
* @param server 查询数据的接口
* @param queryParams 查询数据的参数
* @date 2022年1月4号
* @return Workbook
*/
public static Workbook exportBigExcel(ExportParams entity, List<ExcelExportEntity> excelParams,
IExcelExportServer server, Object queryParams) {
ExcelBatchExportServer batchServer = new ExcelBatchExportServer();
batchServer.init(entity, excelParams);
return batchServer.exportBigExcel(server, queryParams);
}
//update-end---author:liusq Date:20211227 for[LOWCOD-2521]大数据导出方法【全局】----
}

View File

@@ -0,0 +1,457 @@
package org.jeecgframework.poi.excel;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.jeecgframework.core.util.ApplicationContextUtil;
import org.jeecgframework.dict.service.AutoPoiDictServiceI;
import org.jeecgframework.poi.excel.annotation.Excel;
import org.jeecgframework.poi.excel.annotation.ExcelCollection;
import org.jeecgframework.poi.excel.annotation.ExcelTarget;
import org.jeecgframework.poi.excel.annotation.ExcelVerify;
import org.jeecgframework.poi.excel.entity.ImportParams;
import org.jeecgframework.poi.excel.entity.params.ExcelCollectionParams;
import org.jeecgframework.poi.excel.entity.params.ExcelImportEntity;
import org.jeecgframework.poi.excel.entity.params.ExcelVerifyEntity;
import org.jeecgframework.poi.excel.imports.ExcelImportServer;
import org.jeecgframework.poi.exception.excel.ExcelImportException;
import org.jeecgframework.poi.exception.excel.enums.ExcelImportEnum;
import org.jeecgframework.poi.util.ExcelUtil;
import org.jeecgframework.poi.util.PoiPublicUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.InputStream;
import java.io.PushbackInputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.math.BigDecimal;
import java.util.*;
/**
* EXCEL INCLUE CHECK
* 验证excel标题是否存在当前默认有0.880%)即可通过验证
*/
public class ExcelImportCheckUtil {
private final static Logger LOGGER = LoggerFactory.getLogger(ExcelImportCheckUtil.class);
/**当有标题到达多少可以通过验证*/
public static final Double defScreenRate = 0.8;
/**
* check inclue filed match rate
* @param inputstream
* @param pojoClass
* @param params
* @return
*/
public static Boolean check(InputStream inputstream, Class<?> pojoClass, ImportParams params) {
return check(inputstream,pojoClass,params,defScreenRate);
}
/**
* check inclue filed match rate
* @param inputstream
* @param pojoClass
* @param params
* @param screenRate field match rate (defalut:0.8)
* @return
*/
public static Boolean check(InputStream inputstream, Class<?> pojoClass, ImportParams params, Double screenRate) {
Workbook book = null;
int errorNum = 0;
int successNum = 0;
if (!(inputstream.markSupported())) {
inputstream = new PushbackInputStream(inputstream, 8);
}
try {
// if (POIFSFileSystem.hasPOIFSHeader(inputstream)) {
// book = new HSSFWorkbook(inputstream);
// } else if (POIXMLDocument.hasOOXMLHeader(inputstream)) {
// book = new XSSFWorkbook(OPCPackage.open(inputstream));
// }
book = WorkbookFactory.create(inputstream);
LOGGER.info(" >>> poi3升级到4兼容改造工作, pojoClass="+pojoClass);
} catch (Exception e) {
e.printStackTrace();
}
for (int i = 0; i < params.getSheetNum(); i++) {
Row row = null;
//跳过表头和标题行
Iterator<Row> rows;
try{
rows= book.getSheetAt(i).rowIterator();
}catch (Exception e){
//为空说明读取不到故不是excel
throw new RuntimeException("请导入正确格式的excel文件");
}
for (int j = 0; j < params.getTitleRows() + params.getHeadRows(); j++) {
try{
row = rows.next();
}catch (NoSuchElementException e){
//为空说明标题不出在excel格式错误
throw new RuntimeException("请填写内容标题!");
}
}
Sheet sheet = book.getSheetAt(i);
Map<Integer, String> titlemap = null;
try {
titlemap = getTitleMap(sheet, params);
} catch (Exception e) {
e.printStackTrace();
}
Set<Integer> columnIndexSet = titlemap.keySet();
Integer maxColumnIndex = Collections.max(columnIndexSet);
Integer minColumnIndex = Collections.min(columnIndexSet);
while (rows.hasNext() && (row == null || sheet.getLastRowNum() - row.getRowNum() > params.getLastOfInvalidRow())) {
row = rows.next();
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();
}
try {
getAllExcelField(targetId, fileds, excelParams, excelCollection, pojoClass, null);
} catch (Exception e) {
e.printStackTrace();
}
}
try {
int firstCellNum = row.getFirstCellNum();
if (firstCellNum > minColumnIndex) {
firstCellNum = minColumnIndex;
}
int lastCellNum = row.getLastCellNum();
if (lastCellNum < maxColumnIndex + 1) {
lastCellNum = maxColumnIndex + 1;
}
for (int j = firstCellNum, le = lastCellNum; j < le; j++) {
String titleString = (String) titlemap.get(j);
if (excelParams.containsKey(titleString) || Map.class.equals(pojoClass)) {
successNum+=1;
}else{
if(excelCollection.size()>0){
Iterator var33 = excelCollection.iterator();
ExcelCollectionParams param = (ExcelCollectionParams)var33.next();
if (param.getExcelParams().containsKey(titleString)) {
successNum+=1;
}else{
errorNum+=1;
}
}else{
errorNum+=1;
}
}
}
if(successNum<errorNum){
return false;
}else if(successNum>errorNum){
if(errorNum>0){
double newNumber = (double) successNum / (successNum + errorNum);
BigDecimal bg = new BigDecimal(newNumber);
double f1 = bg.setScale(1, BigDecimal.ROUND_HALF_UP).doubleValue();
if(f1<screenRate){
return false;
}else{
return true;
}
}else{
return true;
}
}else if(successNum==errorNum){
return false;
}else{
return false;
}
} catch (ExcelImportException e) {
if (!e.getType().equals(ExcelImportEnum.VERIFY_ERROR)) {
throw new ExcelImportException(e.getType(), e);
}
}
}
}
return null;
}
/**
* 获取文件名称标题
* @Author JEECG
* @date 20201023
* @throws Exception
*/
private static Map<Integer, String> getTitleMap(Sheet sheet, ImportParams params) throws Exception {
Map<Integer, String> titlemap = new HashMap<Integer, String>();
Iterator<Cell> cellTitle = null;
String collectionName = null;
Row headRow = null;
int headBegin = params.getTitleRows();
int allRowNum = sheet.getPhysicalNumberOfRows();
while(headRow == null && headBegin < allRowNum){
headRow = sheet.getRow(headBegin++);
}
if(headRow==null){
throw new Exception("不识别该文件");
}
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);
if(params.isIgnoreHeader(collectionName)){
titlemap.put(cell.getColumnIndex(), value);
}else{
titlemap.put(cell.getColumnIndex(), collectionName + "_" + value);
}
}else{
titlemap.put(cell.getColumnIndex(), value);
}
}
}
}
return titlemap;
}
/**
* 获取key的值,针对不同类型获取不同的值
*
* @Author JEECG
* @date 20201023
* @param cell
* @return
*/
private static String getKeyValue(Cell cell) {
if(cell==null){
return null;
}
Object obj = null;
switch (cell.getCellType()) {
case STRING:
obj = cell.getStringCellValue();
break;
case BOOLEAN:
obj = cell.getBooleanCellValue();
break;
case NUMERIC:
obj = cell.getNumericCellValue();
break;
case FORMULA:
obj = cell.getCellFormula();
break;
}
return obj == null ? null : obj.toString().trim();
}
/**
* 获取需要导出的全部字段
*
*
*
* @param targetId
* 目标ID
* @param fields
* @param excelCollection
* @throws Exception
*/
public static 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();
ParameterizedType pt = (ParameterizedType)field.getGenericType();
Class<?> clz = (Class)pt.getActualTypeArguments()[0];
collection.setType(clz);
getExcelFieldList(targetId, PoiPublicUtil.getClassFields(clz), clz, temp, (List)null);
collection.setExcelParams(temp);
collection.setExcelName(((ExcelCollection)field.getAnnotation(ExcelCollection.class)).name());
additionalCollectionName(collection);
excelCollection.add(collection);
} else if (PoiPublicUtil.isJavaClass(field)) {
addEntityToMap(targetId, field, (ExcelImportEntity)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);
}
}
}
public static 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((List)null, field, targetId)) {
if (PoiPublicUtil.isJavaClass(field)) {
addEntityToMap(targetId, field, (ExcelImportEntity)excelEntity, pojoClass, getMethods, temp);
} else {
List<Method> newMethods = new ArrayList();
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 collection
*/
private static void additionalCollectionName(ExcelCollectionParams collection) {
Set<String> keys = new HashSet();
keys.addAll(collection.getExcelParams().keySet());
Iterator var3 = keys.iterator();
while(var3.hasNext()) {
String key = (String)var3.next();
collection.getExcelParams().put(collection.getExcelName() + "_" + key, collection.getExcelParams().get(key));
collection.getExcelParams().remove(key);
}
}
/**
* 把这个注解解析放到类型对象中
*
* @param targetId
* @param field
* @param excelEntity
* @param pojoClass
* @param getMethods
* @param temp
* @throws Exception
*/
public static 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.setNumFormat(excel.numFormat());
excelEntity.setGroupName(excel.groupName());
//update-begin-author:taoYan date:20180202 for:TASK #2067 【bug excel 问题】excel导入字典文本翻译问题
excelEntity.setMultiReplace(excel.multiReplace());
if(StringUtils.isNotEmpty(excel.dicCode())){
AutoPoiDictServiceI jeecgDictService = null;
try {
jeecgDictService = ApplicationContextUtil.getContext().getBean(AutoPoiDictServiceI.class);
} catch (Exception e) {
}
if(jeecgDictService!=null){
String[] dictReplace = jeecgDictService.queryDict(excel.dictTable(), excel.dicCode(), excel.dicText());
if(excelEntity.getReplace()!=null && dictReplace!=null && dictReplace.length!=0){
excelEntity.setReplace(dictReplace);
}
}
}
//update-end-author:taoYan date:20180202 for:TASK #2067 【bug excel 问题】excel导入字典文本翻译问题
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);
}
public static void getExcelField(String targetId, Field field, ExcelImportEntity excelEntity, Excel excel, Class<?> pojoClass) throws Exception {
excelEntity.setName(getExcelName(excel.name(), targetId));
String fieldname = field.getName();
//update-begin-author:taoyan for:TASK #2798 【例子】导入扩展方法,支持自定义导入字段转换规则
excelEntity.setMethod(PoiPublicUtil.getMethod(fieldname, pojoClass, field.getType(),excel.importConvert()));
//update-end-author:taoyan for:TASK #2798 【例子】导入扩展方法,支持自定义导入字段转换规则
if (StringUtils.isNotEmpty(excel.importFormat())) {
excelEntity.setFormat(excel.importFormat());
} else {
excelEntity.setFormat(excel.format());
}
}
/**
* 判断在这个单元格显示的名称
*
* @param exportName
* @param targetId
* @return
*/
public static String getExcelName(String exportName, String targetId) {
if (exportName.indexOf("_") < 0) {
return exportName;
}
String[] arr = exportName.split(",");
for (String str : arr) {
if (str.indexOf(targetId) != -1) {
return str.split("_")[0];
}
}
return null;
}
/**
* 获取导入校验参数
*
* @param field
* @return
*/
public static 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;
}
}

View File

@@ -0,0 +1,168 @@
/**
* Copyright 2013-2015 JEECG (jeecgos@163.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jeecgframework.poi.excel;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import org.jeecgframework.poi.excel.entity.ImportParams;
import org.jeecgframework.poi.excel.entity.result.ExcelImportResult;
import org.jeecgframework.poi.excel.imports.ExcelImportServer;
import org.jeecgframework.poi.excel.imports.sax.SaxReadExcel;
import org.jeecgframework.poi.excel.imports.sax.parse.ISaxRowRead;
import org.jeecgframework.poi.handler.inter.IExcelReadRowHanlder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Excel 导入工具
*
* @author JEECG
* @date 2013-9-24
* @version 1.0
*/
@SuppressWarnings({ "unchecked" })
public final class ExcelImportUtil {
private ExcelImportUtil() {
}
private static final Logger LOGGER = LoggerFactory.getLogger(ExcelImportUtil.class);
/**
* 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) {
LOGGER.error(e.getMessage(), e);
} finally {
try {
in.close();
} catch (IOException e) {
LOGGER.error(e.getMessage(), e);
}
}
return result;
}
/**
* Excel 导入 数据源IO流,不返回校验结果 导入 字段类型 Integer,Long,Double,Date,String,Boolean
*
* @param file
* @param pojoClass
* @param params
* @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 file
* @param pojoClass
* @param params
* @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) {
LOGGER.error(e.getMessage(), e);
} finally {
try {
in.close();
} catch (IOException e) {
LOGGER.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 file
* @param rowRead
* @return
* @throws Exception
*/
@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 file
* @param rowRead
* @return
* @throws Exception
*/
public static <T> List<T> importExcelBySax(InputStream inputstream, ISaxRowRead rowRead) {
return new SaxReadExcel().readExcel(inputstream, null, null, rowRead, null);
}
}

View File

@@ -0,0 +1,67 @@
package org.jeecgframework.poi.excel;
import org.apache.poi.ss.usermodel.Workbook;
import org.jeecgframework.poi.excel.html.ExcelToHtmlServer;
/**
* Excel 变成界面
*
* @author JEECG
* @date 2015年5月10日 上午11:51:48
*/
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
* @param sheetNum
* sheetNum
* @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();
}
}

View File

@@ -0,0 +1,206 @@
/**
* Copyright 2013-2015 JEECG (jeecgos@163.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jeecgframework.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.lang.annotation.Inherited;
/**
* Excel 导出基本注释
*
* @author JEECG
* @date 2014年6月20日 下午10:25:12
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
//update-begin---author:chenrui ---date:20231221 for[issue/#5248]加强继承扩展便利性------------
@Inherited
//update-end---author:chenrui ---date:20231221 for[issue/#5248]加强继承扩展便利性------------
public @interface Excel {
/**
* 导出时间设置,如果字段是Date类型则不需要设置 数据库如果是string 类型,这个需要设置这个数据库格式
*/
public String databaseFormat() default "yyyyMMddHHmmss";
/**
* 导出的时间格式,以这个是否为空来判断是否需要格式化日期
*/
public String exportFormat() default "";
/**
* 时间格式,相当于同时设置了exportFormat 和 importFormat
*/
public String format() default "";
/**
* 导出时在excel中每个列的高度 单位为字符,一个汉字=2个字符
*/
public double height() default 10;
/**
* 导出类型 1 从file读取_old ,2 是从数据库中读取字节文件, 3文件地址_new, 4网络地址 同样导入也是一样的
*
*/
public int imageType() default 3;
/**
* 导入的时间格式,以这个是否为空来判断是否需要格式化日期
*/
public String importFormat() default "";
/**
* 文字后缀,如% 90 变成90%
*/
public String suffix() default "";
/**
* 是否换行 即支持\n
*/
public boolean isWrap() default true;
/**
* 合并单元格依赖关系,比如第二列合并是基于第一列 则{1}就可以了
*/
public int[] mergeRely() default {};
/**
* 纵向合并内容相同的单元格
*/
public boolean mergeVertical() default false;
/**
* 导出时,对应数据库的字段 主要是用户区分每个字段, 不能有annocation重名的 导出时的列名
* 导出排序跟定义了annotation的字段的顺序有关 可以使用a_id,b_id来确实是否使用
*/
public String name();
/**
* 是否需要纵向合并单元格(用于含有list中,单个的单元格,合并list创建的多个row)
*/
public boolean needMerge() default false;
/**
* 展示到第几个可以使用a_id,b_id来确定不同排序
*/
public String orderNum() default "0";
/**
* 值得替换 导出是{"男_1","女_0"} 导入反过来,所以只用写一个
*/
public String[] replace() default {};
/**
* 导入路径,如果是图片可以填写,默认是upload/className/ IconEntity这个类对应的就是upload/Icon/
*
*/
public String savePath() default "upload";
/**
* 导出类型 1 是文本 2 是图片,3是函数,4是数字 默认是文本
*/
public int type() default 1;
/**
* 导出时在excel中每个列的宽 单位为字符,一个汉字=2个字符 如 以列名列内容中较合适的长度 例如姓名列6 【姓名一般三个字】
* 性别列4【男女占1但是列标题两个汉字】 限制1-255
*/
public double width() default 10;
/**
* 是否自动统计数据,如果是统计,true的话在最后追加一行统计,把所有数据都和 这个处理会吞没异常,请注意这一点
*
* @return
*/
public boolean isStatistics() default false;
/**
* 方法描述: 数据字典表
* 作 者: yiming.zhang
* 日 期: 2014年5月11日-下午5:26:40
* @return
* 返回类型: String
*/
public String dictTable() default "";
/**
* 方法描述: 数据code
* 作 者: yiming.zhang
* 日 期: 2014年5月13日-下午9:37:16
* @return
* 返回类型: String
*/
public String dicCode() default "";
/**
* 方法描述: 数据Text
* 作 者: yiming.zhang
* 日 期: 2014年5月11日-下午5:29:05
* @return
* 返回类型: String
*/
public String dicText() default "";
/**
* 导入数据是否需要转化
* 若是为true,则需要在pojo中加入 方法convertset字段名(String text)
* @return
*/
public boolean importConvert() default false;
/**
* 导出数据是否需要转化
* 若是为true,则需要在pojo中加入方法:convertget字段名()
* @return
*/
public boolean exportConvert() default false;
/**
* 值的替换是否支持替换多个(默认true,若数据库值本来就包含逗号则需要配置该值为false)
* @author taoYan
* @since 2018年8月1日
*/
public boolean multiReplace() default true;
/**
* 父表头
* @return
*/
String groupName() default "";
/**
* 数字格式化,参数是Pattern,使用的对象是DecimalFormat
* @return
*/
String numFormat() default "";
/**
* 是否需要隐藏该列
* @return
*/
public boolean isColumnHidden() default false;
/**
* 固定的某一列,解决不好解析的问题
* @return
*/
public int fixedIndex() default -1;
/**
* 这个是不是超链接,如果是需要实现接口返回对象
* @return
*/
public boolean isHyperlink() default false;
}

View File

@@ -0,0 +1,54 @@
/**
* Copyright 2013-2015 JEECG (jeecgos@163.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jeecgframework.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 JEECG 2013年8月24日
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface ExcelCollection {
/**
* 定义excel导出ID 来限定导出字段,处理一个类对应多个不同名称的情况
*/
public String id() default "";
/**
* 导出时,对应数据库的字段 主要是用户区分每个字段, 不能有annocation重名的 导出时的列名
* 导出排序跟定义了annotation的字段的顺序有关 可以使用a_id,b_id来确实是否使用
*/
public String name();
/**
* 展示到第几个同样可以使用a_id,b_id
*
*/
public String orderNum() default "0";
/**
* 创建时创建的类型 默认值是 arrayList
*/
public Class<?> type() default ArrayList.class;
}

View File

@@ -0,0 +1,49 @@
/**
* Copyright 2013-2015 JEECG (jeecgos@163.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jeecgframework.poi.excel.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 标记是不是导出excel 标记为实体类
*
* @author JEECG
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface ExcelEntity {
/**
* 定义excel导出ID 来限定导出字段,处理一个类对应多个不同名称的情况
*/
public String id() default "";
/**
* 导出时,对应数据库的字段 主要是用户区分每个字段, 不能有annocation重名的 导出时的列名
* 导出排序跟定义了annotation的字段的顺序有关 可以使用a_id,b_id来确实是否使用
*/
public String name() default "";
/**
* 导出时是否展示name对应的文本
* @return
*/
boolean show() default false;
}

View File

@@ -0,0 +1,34 @@
/**
* Copyright 2013-2015 JEECG (jeecgos@163.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jeecgframework.poi.excel.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 标记为excel 创建实体忽略,放置死循环的造成
*
* @author JEECG
* @date 2013-9-24
* @version 1.0
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface ExcelIgnore {
}

View File

@@ -0,0 +1,36 @@
/**
* Copyright 2013-2015 JEECG (jeecgos@163.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jeecgframework.poi.excel.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* excel 导出是用于标记id的
*
* @author JEECG
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE })
public @interface ExcelTarget {
/**
* 定义excel导出ID 来限定导出字段
*/
public String value();
}

View File

@@ -0,0 +1,95 @@
/**
* Copyright 2013-2015 JEECG (jeecgos@163.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jeecgframework.poi.excel.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Excel 导入校验
*
* @author JEECG
* @date 2014年6月23日 下午10:46:26
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface ExcelVerify {
/**
* 接口校验
*
* @return
*/
public boolean interHandler() default false;
/**
* 是电子邮件
*
* @return
*/
public boolean isEmail() default false;
/**
* 是13位移动电话
*
* @return
*/
public boolean isMobile() default false;
/**
* 是座机号码
*
* @return
*/
public boolean isTel() default false;
/**
* 最大长度
*
* @return
*/
public int maxLength() default -1;
/**
* 最小长度
*
* @return
*/
public int minLength() default -1;
/**
* 不允许空
*
* @return
*/
public boolean notNull() default false;
/**
* 正在表达式
*
* @return
*/
public String regex() default "";
/**
* 正在表达式,错误提示信息
*
* @return
*/
public String regexTip() default "数据不符合规范";
}

View File

@@ -0,0 +1,41 @@
/**
* Copyright 2013-2015 JEECG (jeecgos@163.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jeecgframework.poi.excel.entity;
import org.jeecgframework.poi.handler.inter.IExcelDataHandler;
/**
* 基础参数
*
* @author JEECG
* @date 2014年6月20日 下午1:56:52
*/
public class ExcelBaseParams {
/**
* 数据处理接口,以此为主,replace,format都在这后面
*/
private IExcelDataHandler dataHanlder;
public IExcelDataHandler getDataHanlder() {
return dataHanlder;
}
public void setDataHanlder(IExcelDataHandler dataHanlder) {
this.dataHanlder = dataHanlder;
}
}

View File

@@ -0,0 +1,294 @@
/**
* Copyright 2013-2015 JEECG (jeecgos@163.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jeecgframework.poi.excel.entity;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.jeecgframework.poi.excel.entity.enmus.ExcelType;
import org.jeecgframework.poi.excel.export.styler.ExcelExportStylerDefaultImpl;
/**
* Excel 导出参数
*
* @author JEECG
* @version 1.0 2013年8月24日
*/
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 = IndexedColors.WHITE.index;
/**
* 属性说明行的颜色 例如:HSSFColor.SKY_BLUE.index 默认
*/
private short headerColor = IndexedColors.SKY_BLUE.index;
/**
* Excel 导出版本
*/
private ExcelType type = ExcelType.HSSF;
/**
* Excel 导出style
*/
private Class<?> style = ExcelExportStylerDefaultImpl.class;
/**
* 是否创建表头
*/
private boolean isCreateHeadRows = true;
/**
* 本地文件存储根路径 base path
*/
private String imageBasePath;
//update-begin---author:liusq Date:20220104 for[LOWCOD-2521]【autopoi】大数据导出方法【全局】----
/**
* 是否固定表头
*/
private boolean isFixedTitle = true;
/**
* 单sheet最大值
* 03版本默认6W行,07默认100W
*/
private int maxNum = 0;
/**
* 导出时在excel中每个列的高度 单位为字符,一个汉字=2个字符
* 全局设置,优先使用
*/
private short height = 0;
/**
* 只读
*/
private boolean readonly = false;
//update-end---author:liusq Date:20220104 for[LOWCOD-2521]【autopoi】大数据导出方法【全局】----
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 ExportParams(String title, String secondTitle, String sheetName,String imageBasePath) {
this.title = title;
this.secondTitle = secondTitle;
this.sheetName = sheetName;
this.imageBasePath = imageBasePath;
}
public short getColor() {
return color;
}
public String[] getExclusions() {
return exclusions;
}
public short getHeaderColor() {
return headerColor;
}
public String getSecondTitle() {
return secondTitle;
}
public short getSecondTitleHeight() {
return (short) (secondTitleHeight * 50);
}
public String getSheetName() {
return sheetName;
}
public String getTitle() {
return title;
}
public short getTitleHeight() {
return (short) (titleHeight * 50);
}
public boolean isAddIndex() {
return addIndex;
}
public void setAddIndex(boolean addIndex) {
this.addIndex = addIndex;
}
public void setColor(short color) {
this.color = color;
}
public void setExclusions(String[] exclusions) {
this.exclusions = exclusions;
}
public void setHeaderColor(short headerColor) {
this.headerColor = headerColor;
}
public void setSecondTitle(String secondTitle) {
this.secondTitle = secondTitle;
}
public void setSecondTitleHeight(short secondTitleHeight) {
this.secondTitleHeight = secondTitleHeight;
}
public void setSheetName(String sheetName) {
this.sheetName = sheetName;
}
public void setTitle(String title) {
this.title = title;
}
public void setTitleHeight(short titleHeight) {
this.titleHeight = titleHeight;
}
public ExcelType getType() {
return type;
}
public void setType(ExcelType type) {
this.type = type;
}
public String getIndexName() {
return indexName;
}
public void setIndexName(String indexName) {
this.indexName = indexName;
}
public Class<?> getStyle() {
return style;
}
public void setStyle(Class<?> style) {
this.style = style;
}
public int getFreezeCol() {
return freezeCol;
}
public void setFreezeCol(int freezeCol) {
this.freezeCol = freezeCol;
}
public boolean isCreateHeadRows() {
return isCreateHeadRows;
}
public void setCreateHeadRows(boolean isCreateHeadRows) {
this.isCreateHeadRows = isCreateHeadRows;
}
public String getImageBasePath() {
return imageBasePath;
}
public void setImageBasePath(String imageBasePath) {
this.imageBasePath = imageBasePath;
}
public int getMaxNum() {
return maxNum;
}
public void setMaxNum(int maxNum) {
this.maxNum = maxNum;
}
public short getHeight() {
return height == -1 ? -1 : (short) (height * 50);
}
public void setHeight(short height) {
this.height = height;
}
public boolean isFixedTitle() {
return isFixedTitle;
}
public void setFixedTitle(boolean fixedTitle) {
isFixedTitle = fixedTitle;
}
public boolean isReadonly() {
return readonly;
}
public void setReadonly(boolean readonly) {
this.readonly = readonly;
}
}

View File

@@ -0,0 +1,206 @@
/**
* Copyright 2013-2015 JEECG (jeecgos@163.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jeecgframework.poi.excel.entity;
import org.jeecgframework.poi.handler.inter.IExcelVerifyHandler;
import java.util.List;
/**
* 导入参数设置
*
* @author JEECG
* @date 2013-9-24
* @version 1.0
*/
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;
//update-begin-author:liusq date:20220605 for:https://gitee.com/jeecg/jeecg-boot/issues/I57UPC 导入 ImportParams 中没有startSheetIndex参数
/**
* 开始读取的sheet位置,默认为0
*/
private int startSheetIndex = 0;
//update-end-author:liusq date:20220605 for:https://gitee.com/jeecg/jeecg-boot/issues/I57UPC 导入 ImportParams 中没有startSheetIndex参数
//update-begin-author:taoyan date:20211210 for:https://gitee.com/jeecg/jeecg-boot/issues/I45C32 导入空白sheet报错
/**
* 上传表格需要读取的sheet 数量,默认为0
*/
private int sheetNum = 0;
//update-end-author:taoyan date:20211210 for:https://gitee.com/jeecg/jeecg-boot/issues/I45C32 导入空白sheet报错
/**
* 是否需要保存上传的Excel,默认为false
*/
private boolean needSave = false;
/**
* 保存上传的Excel目录,默认是 如 TestEntity这个类保存路径就是
* upload/excelUpload/Test/yyyyMMddHHmss_***** 保存名称上传时间_五位随机数
*/
private String saveUrl = "upload/excelUpload";
/**
* 校验处理接口
*/
private IExcelVerifyHandler verifyHanlder;
/**
* 最后的无效行数
*/
private int lastOfInvalidRow = 0;
/**
* 不需要解析的表头 只作为多表头展示,无字段与其绑定
*/
private List<String> ignoreHeaderList;
/**
* 指定导入的sheetName
*/
private String sheetName;
/**
* 图片列 集合
*/
private List<String> imageList;
public int getHeadRows() {
return headRows;
}
public int getKeyIndex() {
return keyIndex;
}
public String getSaveUrl() {
return saveUrl;
}
public int getSheetNum() {
return sheetNum;
}
public int getStartRows() {
return startRows;
}
public int getTitleRows() {
return titleRows;
}
public IExcelVerifyHandler getVerifyHanlder() {
return verifyHanlder;
}
public boolean isNeedSave() {
return needSave;
}
public void setHeadRows(int headRows) {
this.headRows = headRows;
}
public void setKeyIndex(int keyIndex) {
this.keyIndex = keyIndex;
}
public void setNeedSave(boolean needSave) {
this.needSave = needSave;
}
public void setSaveUrl(String saveUrl) {
this.saveUrl = saveUrl;
}
public void setSheetNum(int sheetNum) {
this.sheetNum = sheetNum;
}
public void setStartRows(int startRows) {
this.startRows = startRows;
}
public void setTitleRows(int titleRows) {
this.titleRows = titleRows;
}
public void setVerifyHanlder(IExcelVerifyHandler verifyHanlder) {
this.verifyHanlder = verifyHanlder;
}
public int getLastOfInvalidRow() {
return lastOfInvalidRow;
}
public void setLastOfInvalidRow(int lastOfInvalidRow) {
this.lastOfInvalidRow = lastOfInvalidRow;
}
public List<String> getImageList() {
return imageList;
}
public void setImageList(List<String> imageList) {
this.imageList = imageList;
}
public List<String> getIgnoreHeaderList() {
return ignoreHeaderList;
}
public void setIgnoreHeaderList(List<String> ignoreHeaderList) {
this.ignoreHeaderList = ignoreHeaderList;
}
public String getSheetName() {
return sheetName;
}
public void setSheetName(String sheetName) {
this.sheetName = sheetName;
}
/**
* 根据表头显示的文字 判断是否忽略该表头
* @param text
* @return
*/
public boolean isIgnoreHeader(String text){
if(ignoreHeaderList!=null && ignoreHeaderList.indexOf(text)>=0){
return true;
}
return false;
}
public int getStartSheetIndex() {
return startSheetIndex;
}
public void setStartSheetIndex(int startSheetIndex) {
this.startSheetIndex = startSheetIndex;
}
}

View File

@@ -0,0 +1,218 @@
/**
* Copyright 2013-2015 JEECG (jeecgos@163.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jeecgframework.poi.excel.entity;
import org.jeecgframework.poi.excel.export.styler.ExcelExportStylerDefaultImpl;
/**
* 模板导出参数设置
*
* @author JEECG
* @date 2013-10-17
* @version 1.0
*/
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";
//列循环支持
private boolean colForEach = false;
/**
* 默认构造器
*/
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;
}
}
public int getHeadingRows() {
return headingRows;
}
public int getHeadingStartRow() {
return headingStartRow;
}
public String[] getSheetName() {
return sheetName;
}
public Integer[] getSheetNum() {
return sheetNum;
}
public String getTemplateUrl() {
return templateUrl;
}
public void setHeadingRows(int headingRows) {
this.headingRows = headingRows;
}
public void setHeadingStartRow(int headingStartRow) {
this.headingStartRow = headingStartRow;
}
public void setSheetName(String[] sheetName) {
this.sheetName = sheetName;
}
public void setSheetName(String sheetName) {
this.sheetName = new String[] { sheetName };
}
public void setSheetNum(Integer[] sheetNum) {
this.sheetNum = sheetNum;
}
public void setSheetNum(Integer sheetNum) {
this.sheetNum = new Integer[] { sheetNum };
}
public void setTemplateUrl(String templateUrl) {
this.templateUrl = templateUrl;
}
public Class<?> getStyle() {
return style;
}
public void setStyle(Class<?> style) {
this.style = style;
}
public int getDataSheetNum() {
return dataSheetNum;
}
public void setDataSheetNum(int dataSheetNum) {
this.dataSheetNum = dataSheetNum;
}
public boolean isScanAllsheet() {
return scanAllsheet;
}
public void setScanAllsheet(boolean scanAllsheet) {
this.scanAllsheet = scanAllsheet;
}
public String getTempParams() {
return tempParams;
}
public void setTempParams(String tempParams) {
this.tempParams = tempParams;
}
public boolean isColForEach() {
return colForEach;
}
public void setColForEach(boolean colForEach) {
this.colForEach = colForEach;
}
}

View File

@@ -0,0 +1,28 @@
/**
* Copyright 2013-2015 JEECG (jeecgos@163.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jeecgframework.poi.excel.entity.enmus;
/**
* Cell 值得类型
*
* @author JEECG
* @date 2014年12月29日 下午10:20:49
*/
public enum CellValueType {
String, Number, Boolean, Date, TElement, Null, None;
}

View File

@@ -0,0 +1,48 @@
/**
* Copyright 2013-2015 JEECG (jeecgos@163.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jeecgframework.poi.excel.entity.enmus;
import org.jeecgframework.poi.excel.export.styler.ExcelExportStylerBorderImpl;
import org.jeecgframework.poi.excel.export.styler.ExcelExportStylerColorImpl;
import org.jeecgframework.poi.excel.export.styler.ExcelExportStylerDefaultImpl;
/**
* 插件提供的几个默认样式
*
* @author JEECG
* @date 2015年1月9日 下午9:02:24
*/
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;
}
}

View File

@@ -0,0 +1,28 @@
/**
* Copyright 2013-2015 JEECG (jeecgos@163.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jeecgframework.poi.excel.entity.enmus;
/**
* Excel Type
*
* @author JEECG
* @date 2014年12月29日 下午9:08:21
*/
public enum ExcelType {
HSSF, XSSF;
}

View File

@@ -0,0 +1,184 @@
/**
* Copyright 2013-2015 JEECG (jeecgos@163.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jeecgframework.poi.excel.entity.params;
import java.lang.reflect.Method;
import java.util.List;
/**
* Excel 导入导出基础对象类
*
* @author JEECG
* @date 2014年6月20日 下午2:26:09
*/
public class ExcelBaseEntity {
/**
* 对应name
*/
protected String name;
/**
* 对应type
*/
private int type = 1;
/**
* 数据库格式
*/
private String databaseFormat;
/**
* 导出日期格式
*/
private String format;
/**
* 数字格式化,参数是Pattern,使用的对象是DecimalFormat
*/
private String numFormat;
/**
* 替换值表达式 "男_1","女_0"
*/
private String[] replace;
/**
* 替换是否是替换多个值
*/
private boolean multiReplace;
/**
* 表头组名称
*/
private String groupName;
/**
* set/get方法
*/
private Method method;
/**
* 固定的列
*/
private Integer fixedIndex;
/**
* 字典名称
*/
private String dict;
/**
* 这个是不是超链接,如果是需要实现接口返回对象
*/
private boolean hyperlink;
private List<Method> methods;
public String getDatabaseFormat() {
return databaseFormat;
}
public String getFormat() {
return format;
}
public Method getMethod() {
return method;
}
public List<Method> getMethods() {
return methods;
}
public String getName() {
return name;
}
public String[] getReplace() {
return replace;
}
public int getType() {
return type;
}
public void setDatabaseFormat(String databaseFormat) {
this.databaseFormat = databaseFormat;
}
public void setFormat(String format) {
this.format = format;
}
public void setMethod(Method method) {
this.method = method;
}
public void setMethods(List<Method> methods) {
this.methods = methods;
}
public void setName(String name) {
this.name = name;
}
public void setReplace(String[] replace) {
this.replace = replace;
}
public void setType(int type) {
this.type = type;
}
public boolean isMultiReplace() {
return multiReplace;
}
public void setMultiReplace(boolean multiReplace) {
this.multiReplace = multiReplace;
}
public String getNumFormat() {
return numFormat;
}
public void setNumFormat(String numFormat) {
this.numFormat = numFormat;
}
public String getGroupName() {
return groupName;
}
public void setGroupName(String groupName) {
this.groupName = groupName;
}
public Integer getFixedIndex() {
return fixedIndex;
}
public void setFixedIndex(Integer fixedIndex) {
this.fixedIndex = fixedIndex;
}
public String getDict() {
return dict;
}
public void setDict(String dict) {
this.dict = dict;
}
public boolean isHyperlink() {
return hyperlink;
}
public void setHyperlink(boolean hyperlink) {
this.hyperlink = hyperlink;
}
}

View File

@@ -0,0 +1,77 @@
/**
* Copyright 2013-2015 JEECG (jeecgos@163.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jeecgframework.poi.excel.entity.params;
import java.util.Map;
/**
* Excel 对于的 Collection
*
* @author JEECG
* @date 2013-9-26
* @version 1.0
*/
public class ExcelCollectionParams {
/**
* 集合对应的名称
*/
private String name;
/**
* Excel 列名称
*/
private String excelName;
/**
* 实体对象
*/
private Class<?> type;
/**
* 这个list下面的参数集合实体对象
*/
private Map<String, ExcelImportEntity> excelParams;
public Map<String, ExcelImportEntity> getExcelParams() {
return excelParams;
}
public String getName() {
return name;
}
public Class<?> getType() {
return type;
}
public void setExcelParams(Map<String, ExcelImportEntity> excelParams) {
this.excelParams = excelParams;
}
public void setName(String name) {
this.name = name;
}
public void setType(Class<?> type) {
this.type = type;
}
public String getExcelName() {
return excelName;
}
public void setExcelName(String excelName) {
this.excelName = excelName;
}
}

View File

@@ -0,0 +1,306 @@
/**
* Copyright 2013-2015 JEECG (jeecgos@163.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jeecgframework.poi.excel.entity.params;
import java.util.ArrayList;
import java.util.List;
/**
* excel 导出工具类,对cell类型做映射
*
* @author JEECG
* @version 1.0 2013年8月24日
*/
public class ExcelExportEntity extends ExcelBaseEntity implements Comparable<ExcelExportEntity> {
/**
* 如果是MAP导出,这个是map的key
*/
private Object key;
private double width = 10;
private double height = 10;
/**
* 图片的类型,1是文件地址(class目录),2是数据库字节,3是文件地址(磁盘目录)4网络图片
*/
private int exportImageType = 3;
/**
* 图片储存位置(磁盘目录) 用于导出获取图片绝对路径
*/
private String imageBasePath;
/**
* 排序顺序
*/
private int orderNum = 0;
/**
* 是否支持换行
*/
private boolean isWrap;
/**
* 是否需要合并
*/
private boolean needMerge;
/**
* 单元格纵向合并
*/
private boolean mergeVertical;
/**
* 合并依赖
*/
private int[] mergeRely;
/**
* 后缀
*/
private String suffix;
/**
* 统计
*/
private boolean isStatistics;
/**
* 是否横向合并
*/
private boolean colspan;
/**
* 被横向合并的列名称
*/
private List<String> subColumnList;
/**
* 父表头的名称
*/
private String groupName;
/**
* 是否隐藏列
*/
private boolean isColumnHidden;
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;
}
/**
* 构造器
* @param name 描述-文字
* @param key 存储key 如果是MAP导出,这个是map的key
* @param colspan 是否为合并列a,b列公用一个表头c,则a,b,c都需要设置为true
*/
public ExcelExportEntity(String name, Object key, boolean colspan) {
super.name = name;
this.key = key;
this.colspan = colspan;
this.needMerge = colspan;
}
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;
}
public String getImageBasePath() {
return imageBasePath;
}
public void setImageBasePath(String imageBasePath) {
this.imageBasePath = imageBasePath;
}
public boolean isColspan() {
return colspan;
}
public void setColspan(boolean colspan) {
this.colspan = colspan;
}
public List<String> getSubColumnList() {
return subColumnList;
}
public void setSubColumnList(List<String> subColumnList) {
this.subColumnList = subColumnList;
}
public String getGroupName() {
return groupName;
}
public void setGroupName(String groupName) {
this.groupName = groupName;
}
public boolean isColumnHidden() {
return isColumnHidden;
}
public void setColumnHidden(boolean columnHidden) {
isColumnHidden = columnHidden;
}
/**
* 是否为合并子列
* @return
*/
public boolean isSubColumn(){
return this.colspan && (this.subColumnList==null || this.subColumnList.size()==0);
}
/**
* 是否为合并父列
* @return
*/
public boolean isMergeColumn(){
return this.colspan && this.subColumnList!=null && this.subColumnList.size()>0;
}
/**
* 获取被合并的子列
* @param all
* @return
*/
public List<ExcelExportEntity> initSubExportEntity(List<ExcelExportEntity> all){
List<ExcelExportEntity> sub = new ArrayList<ExcelExportEntity>();
for (ExcelExportEntity temp : all) {
if(this.subColumnList.contains(temp.getKey())){
sub.add(temp);
}
}
this.setList(sub);
return sub;
}
@Override
public int compareTo(ExcelExportEntity prev) {
return this.getOrderNum() - prev.getOrderNum();
}
}

View File

@@ -0,0 +1,125 @@
package org.jeecgframework.poi.excel.entity.params;
import java.io.Serializable;
import java.util.Stack;
import org.apache.poi.ss.usermodel.CellStyle;
/**
* 模板for each是的参数
* @author JueYue
* @date 2015年4月29日 下午9:22:48
*/
public class ExcelForEachParams implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
/**
* key
*/
private String name;
/**
* key
*/
private Stack<String> tempName;
/**
* 模板的cellStyle
*/
private CellStyle cellStyle;
/**
* 行高
*/
private short height;
/**
* 常量值
*/
private String constValue;
/**
* 列合并
*/
private int colspan = 1;
/**
* 行合并
*/
private int rowspan = 1;
/**
* 行合并
*/
private boolean collectCell;
public ExcelForEachParams() {
}
public ExcelForEachParams(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;
}
public String getConstValue() {
return constValue;
}
public void setConstValue(String constValue) {
this.constValue = constValue;
}
public int getColspan() {
return colspan;
}
public void setColspan(int colspan) {
this.colspan = colspan;
}
public int getRowspan() {
return rowspan;
}
public void setRowspan(int rowspan) {
this.rowspan = rowspan;
}
public boolean isCollectCell() {
return collectCell;
}
public void setCollectCell(boolean collectCell) {
this.collectCell = collectCell;
}
public Stack<String> getTempName() {
return tempName;
}
public void setTempName(Stack<String> tempName) {
this.tempName = tempName;
}
}

View File

@@ -0,0 +1,110 @@
/**
* Copyright 2013-2015 JEECG (jeecgos@163.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jeecgframework.poi.excel.entity.params;
import java.util.List;
/**
* excel 导入工具类,对cell类型做映射
*
* @author JEECG
* @version 1.0 2013年8月24日
*/
public class ExcelImportEntity extends ExcelBaseEntity {
/**
* 对应 Collection NAME
*/
private String collectionName;
/**
* 保存图片的地址 当saveType设置为3/4时此值可以设置为local,minio,alioss
*/
private String saveUrl;
/**
* 保存图片的类型,1是文件_old,2是数据库字节,3文件地址_new,4网络地址
*/
private int saveType;
/**
* 对应exportType
*/
private String classType;
/**
* 校驗參數
*/
private ExcelVerifyEntity verify;
/**
* 后缀
*/
private String suffix;
private List<ExcelImportEntity> list;
public String getClassType() {
return classType;
}
public String getCollectionName() {
return collectionName;
}
public List<ExcelImportEntity> getList() {
return list;
}
public int getSaveType() {
return saveType;
}
public String getSaveUrl() {
return saveUrl;
}
public ExcelVerifyEntity getVerify() {
return verify;
}
public void setClassType(String classType) {
this.classType = classType;
}
public void setCollectionName(String collectionName) {
this.collectionName = collectionName;
}
public void setList(List<ExcelImportEntity> list) {
this.list = list;
}
public void setSaveType(int saveType) {
this.saveType = saveType;
}
public void setSaveUrl(String saveUrl) {
this.saveUrl = saveUrl;
}
public void setVerify(ExcelVerifyEntity verify) {
this.verify = verify;
}
public String getSuffix() {
return suffix;
}
public void setSuffix(String suffix) {
this.suffix = suffix;
}
}

View File

@@ -0,0 +1,66 @@
package org.jeecgframework.poi.excel.entity.params;
import java.io.Serializable;
import org.apache.poi.ss.usermodel.CellStyle;
/**
* 模板便利是的参数
*
* @author JEECG
* @date 2015年4月29日 下午9:22:48
*/
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;
}
}

View File

@@ -0,0 +1,159 @@
/**
* Copyright 2013-2015 JEECG (jeecgos@163.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jeecgframework.poi.excel.entity.params;
/**
* Excel 校验对象
*
* @author JEECG
* @date 2014年6月29日 下午4:24:59
*/
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;
public int getMaxLength() {
return maxLength;
}
public int getMinLength() {
return minLength;
}
public String getRegex() {
return regex;
}
public String getRegexTip() {
return regexTip;
}
public boolean isEmail() {
return isEmail;
}
public boolean isInterHandler() {
return interHandler;
}
public boolean isMobile() {
return isMobile;
}
public boolean isNotNull() {
return notNull;
}
public boolean isTel() {
return isTel;
}
public void setEmail(boolean isEmail) {
this.isEmail = isEmail;
}
public void setInterHandler(boolean interHandler) {
this.interHandler = interHandler;
}
public void setMaxLength(int maxLength) {
this.maxLength = maxLength;
}
public void setMinLength(int minLength) {
this.minLength = minLength;
}
public void setMobile(boolean isMobile) {
this.isMobile = isMobile;
}
public void setNotNull(boolean notNull) {
this.notNull = notNull;
}
public void setRegex(String regex) {
this.regex = regex;
}
public void setRegexTip(String regexTip) {
this.regexTip = regexTip;
}
public void setTel(boolean isTel) {
this.isTel = isTel;
}
}

View File

@@ -0,0 +1,84 @@
/**
* Copyright 2013-2015 JEECG (jeecgos@163.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jeecgframework.poi.excel.entity.params;
import java.util.List;
/**
* 合并单元格使用对象
*
* Created by jue on 14-6-11.
*/
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;
}
}

View File

@@ -0,0 +1,79 @@
/**
* Copyright 2013-2015 JEECG (jeecgos@163.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jeecgframework.poi.excel.entity.result;
import java.util.List;
import org.apache.poi.ss.usermodel.Workbook;
/**
* 导入返回类
*
* @author JEECG
* @date 2014年6月29日 下午5:12:10
*/
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;
}
}

View File

@@ -0,0 +1,63 @@
/**
* Copyright 2013-2015 JEECG (jeecgos@163.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jeecgframework.poi.excel.entity.result;
/**
* Excel导入处理返回结果
*
* @author JEECG
* @date 2014年6月23日 下午11:03:29
*/
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;
}
}

View File

@@ -0,0 +1,62 @@
/**
* Copyright 2013-2015 JEECG (jeecgos@163.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jeecgframework.poi.excel.entity.sax;
import org.jeecgframework.poi.excel.entity.enmus.CellValueType;
/**
* Cell 对象
*
* @author JEECG
* @date 2014年12月29日 下午10:12:57
*/
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 + "]";
}
}

View File

@@ -0,0 +1,43 @@
/**
* Copyright 2013-2015 JEECG (jeecgos@163.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jeecgframework.poi.excel.entity.vo;
/**
* 基础常量 Created by jue on 14-4-21.
*/
public interface PoiBaseConstants {
/**
* 字段属性对应方法
*/
public static String GET = "get";
/**
* 字段属性对应方法
*/
public static String SET = "set";
/**
* 字段属性对应方法
*/
public static String IS = "is";
/**
* 是否增加属性列
*/
public static String IS_ADD_INDEX = "isAddIndex";
/**
* 字段属性对应convert方法
*/
public static String CONVERT = "convert";
}

View File

@@ -0,0 +1,200 @@
package org.jeecgframework.poi.excel.export;
import org.apache.poi.ss.usermodel.Drawing;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.jeecgframework.poi.excel.annotation.ExcelTarget;
import org.jeecgframework.poi.excel.entity.ExportParams;
import org.jeecgframework.poi.excel.entity.enmus.ExcelType;
import org.jeecgframework.poi.excel.entity.params.ExcelExportEntity;
import org.jeecgframework.poi.excel.entity.vo.PoiBaseConstants;
import org.jeecgframework.poi.excel.export.styler.IExcelExportStyler;
import org.jeecgframework.poi.exception.excel.ExcelExportException;
import org.jeecgframework.poi.exception.excel.enums.ExcelExportEnum;
import org.jeecgframework.poi.handler.inter.IExcelExportServer;
import org.jeecgframework.poi.handler.inter.IWriter;
import org.jeecgframework.poi.util.PoiExcelGraphDataUtil;
import org.jeecgframework.poi.util.PoiPublicUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.Field;
import java.util.*;
import static org.jeecgframework.poi.excel.ExcelExportUtil.USE_SXSSF_LIMIT;
/**
* 提供批次插入服务
* @author liusq
* @date 2022年1月4日
*/
public class ExcelBatchExportServer extends ExcelExportServer implements IWriter<Workbook> {
private final static Logger LOGGER = LoggerFactory.getLogger(ExcelBatchExportServer.class);
private Workbook workbook;
private Sheet sheet;
private List<ExcelExportEntity> excelParams;
private ExportParams entity;
private int titleHeight;
private Drawing patriarch;
private short rowHeight;
private int index;
public void init(ExportParams entity, Class<?> pojoClass) {
List<ExcelExportEntity> excelParams = createExcelExportEntityList(entity, pojoClass);
init(entity, excelParams);
}
/**
* 初始化数据
* @param entity 导出参数
* @param excelParams
*/
public void init(ExportParams entity, List<ExcelExportEntity> excelParams) {
LOGGER.debug("ExcelBatchExportServer only support SXSSFWorkbook");
entity.setType(ExcelType.XSSF);
workbook = new SXSSFWorkbook();
this.entity = entity;
this.excelParams = excelParams;
super.type = entity.getType();
createSheet(workbook, entity, excelParams);
if (entity.getMaxNum() == 0) {
entity.setMaxNum(USE_SXSSF_LIMIT);
}
insertDataToSheet(workbook, entity, excelParams, null, sheet);
}
public List<ExcelExportEntity> createExcelExportEntityList(ExportParams entity, Class<?> pojoClass) {
try {
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);
return excelParams;
} catch (Exception e) {
throw new ExcelExportException(ExcelExportEnum.EXPORT_ERROR, e);
}
}
public void createSheet(Workbook workbook, ExportParams entity, List<ExcelExportEntity> excelParams) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Excel export start ,List<ExcelExportEntity> is {}", excelParams);
LOGGER.debug("Excel version is {}",
entity.getType().equals(ExcelType.HSSF) ? "03" : "07");
}
if (workbook == null || entity == null || excelParams == null) {
throw new ExcelExportException(ExcelExportEnum.PARAMETER_ERROR);
}
try {
try {
sheet = workbook.createSheet(entity.getSheetName());
} catch (Exception e) {
// 重复遍历,出现了重名现象,创建非指定的名称Sheet
sheet = workbook.createSheet();
}
} catch (Exception e) {
throw new ExcelExportException(ExcelExportEnum.EXPORT_ERROR, e);
}
}
@Override
protected void insertDataToSheet(Workbook workbook, ExportParams entity,
List<ExcelExportEntity> entityList, Collection<? extends Map<?, ?>> dataSet,
Sheet sheet) {
try {
dataHanlder = entity.getDataHanlder();
if (dataHanlder != null && dataHanlder.getNeedHandlerFields() != null) {
needHanlderList = Arrays.asList(dataHanlder.getNeedHandlerFields());
}
// 创建表格样式
setExcelExportStyler((IExcelExportStyler) entity.getStyle()
.getConstructor(Workbook.class).newInstance(workbook));
patriarch = PoiExcelGraphDataUtil.getDrawingPatriarch(sheet);
List<ExcelExportEntity> excelParams = new ArrayList<ExcelExportEntity>();
if (entity.isAddIndex()) {
excelParams.add(indexExcelEntity(entity));
}
excelParams.addAll(entityList);
sortAllParams(excelParams);
this.index = entity.isCreateHeadRows()
? createHeaderAndTitle(entity, sheet, workbook, excelParams) : 0;
titleHeight = index;
setCellWith(excelParams, sheet);
setColumnHidden(excelParams, sheet);
rowHeight = getRowHeight(excelParams);
setCurrentIndex(1);
} catch (Exception e) {
LOGGER.error(e.getMessage(), e);
throw new ExcelExportException(ExcelExportEnum.EXPORT_ERROR, e.getCause());
}
}
public Workbook exportBigExcel(IExcelExportServer server, Object queryParams) {
int page = 1;
List<Object> list = server
.selectListForExcelExport(queryParams, page++);
while (list != null && list.size() > 0) {
write(list);
list = server.selectListForExcelExport(queryParams, page++);
}
return close();
}
@Override
public Workbook get() {
return this.workbook;
}
@Override
public IWriter<Workbook> write(Collection data) {
if (sheet.getLastRowNum() + data.size() > entity.getMaxNum()) {
sheet = workbook.createSheet();
index = 0;
}
Iterator<?> its = data.iterator();
while (its.hasNext()) {
Object t = its.next();
try {
index += createCells(patriarch, index, t, excelParams, sheet, workbook, rowHeight, 0)[0];
} catch (Exception e) {
LOGGER.error(e.getMessage(), e);
throw new ExcelExportException(ExcelExportEnum.EXPORT_ERROR, e);
}
}
return this;
}
@Override
public Workbook close() {
if (entity.getFreezeCol() != 0) {
sheet.createFreezePane(entity.getFreezeCol(), titleHeight, entity.getFreezeCol(), titleHeight);
}
mergeCells(sheet, excelParams, titleHeight);
// 创建合计信息
addStatisticsRow(getExcelExportStyler().getStyles(true, null), sheet);
return workbook;
}
/**
* 添加Index列
*/
@Override
public ExcelExportEntity indexExcelEntity(ExportParams entity) {
ExcelExportEntity exportEntity = new ExcelExportEntity();
//保证是第一排
exportEntity.setOrderNum(Integer.MIN_VALUE);
exportEntity.setNeedMerge(true);
exportEntity.setName(entity.getIndexName());
exportEntity.setWidth(10);
exportEntity.setFormat(PoiBaseConstants.IS_ADD_INDEX);
return exportEntity;
}
}

View File

@@ -0,0 +1,454 @@
/**
* Copyright 2013-2015 JEECG (jeecgos@163.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jeecgframework.poi.excel.export;
import java.lang.reflect.Field;
import java.util.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.jeecgframework.poi.excel.annotation.ExcelTarget;
import org.jeecgframework.poi.excel.entity.ExportParams;
import org.jeecgframework.poi.excel.entity.enmus.ExcelType;
import org.jeecgframework.poi.excel.entity.params.ExcelExportEntity;
import org.jeecgframework.poi.excel.entity.vo.PoiBaseConstants;
import org.jeecgframework.poi.excel.export.base.ExcelExportBase;
import org.jeecgframework.poi.excel.export.styler.IExcelExportStyler;
import org.jeecgframework.poi.exception.excel.ExcelExportException;
import org.jeecgframework.poi.exception.excel.enums.ExcelExportEnum;
import org.jeecgframework.poi.util.PoiExcelGraphDataUtil;
import org.jeecgframework.poi.util.PoiPublicUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Excel导出服务
*
* @author JEECG
* @date 2014年6月17日 下午5:30:54
*/
public class ExcelExportServer extends ExcelExportBase {
private final static Logger LOGGER = LoggerFactory.getLogger(ExcelExportServer.class);
// 最大行数,超过自动多Sheet
private int MAX_NUM = 60000;
protected 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);
//update-begin---author:liusq Date:20211217 for[LOWCOD-2521]【autopoi】大数据导出方法【全局】----
if (entity.isFixedTitle()) {
sheet.createFreezePane(0, rows, 0, rows);
}
//update-begin---author:liusq Date:20211217 for[LOWCOD-2521]【autopoi】大数据导出方法【全局】----
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);
}
//update-begin-author:wangshuai date:20201118 for:一对多导出needMerge 子表数据对应数量小于2时报错 github#1840、gitee I1YH6B
try {
sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, feildWidth));
}catch (IllegalArgumentException e){
LOGGER.error("合并单元格错误日志:"+e.getMessage());
e.fillInStackTrace();
}
//update-end-author:wangshuai date:20201118 for:一对多导出needMerge 子表数据对应数量小于2时报错 github#1840、gitee I1YH6B
if (entity.getSecondTitle() != null) {
row = sheet.createRow(1);
row.setHeight(entity.getSecondTitleHeight());
//update-begin-author:liusq date:20230407 for:[issue/4342]autopoi导出带副标题的数据表副标题缺左边框
CellStyle style = getExcelExportStyler().getHeaderStyle(entity.getHeaderColor());
style.setAlignment(HorizontalAlignment.RIGHT);
//update-end-author:liusq date:20230407 for:[issue/4342]autopoi导出带副标题的数据表副标题缺左边框
createStringCell(row, 0, entity.getSecondTitle(), style, null);
for (int i = 1; i <= feildWidth; i++) {
createStringCell(row, i, "", getExcelExportStyler().getHeaderStyle(entity.getHeaderColor()), null);
}
//update-begin-author:wangshuai date:20201118 for:一对多导出needMerge 子表数据对应数量小于2时报错 github#1840、gitee I1YH6B
try{
sheet.addMergedRegion(new CellRangeAddress(1, 1, 0, feildWidth));
}catch (IllegalArgumentException e){
LOGGER.error("合并单元格错误日志:"+e.getMessage());
e.fillInStackTrace();
}
//update-end-author:wangshuai date:20201118 for:一对多导出needMerge 子表数据对应数量小于2时报错 github#1840、gitee I1YH6B
return 2;
}
return 1;
}
public void createSheet(Workbook workbook, ExportParams entity, Class<?> pojoClass, Collection<?> dataSet, String[] exportFields) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Excel export start ,class is {}", pojoClass);
LOGGER.debug("Excel version is {}", entity.getType().equals(ExcelType.HSSF) ? "03" : "07");
}
if (workbook == null || entity == null || pojoClass == null || dataSet == null) {
throw new ExcelExportException(ExcelExportEnum.PARAMETER_ERROR);
}
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) {
String[] needHandlerFields = dataHanlder.getNeedHandlerFields();
if(needHandlerFields!=null && needHandlerFields.length>0){
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));
}
// 得到所有字段
Field fileds[] = PoiPublicUtil.getClassFields(pojoClass);
//---update-begin-----autor:scott------date:20191016-------for:导出字段支持自定义--------
//支持自定义导出字段
if (exportFields != null) {
List<Field> list = new ArrayList<Field>(Arrays.asList(fileds));
for (int i = 0; i < list.size(); i++) {
if (!Arrays.asList(exportFields).contains(list.get(i).getName())) {
list.remove(i);
i--;
}
}
if (list != null && list.size() > 0) {
fileds = list.toArray(new Field[0]);
} else {
fileds = null;
}
}
//---update-end-----autor:scott------date:20191016-------for:导出字段支持自定义--------
ExcelTarget etarget = pojoClass.getAnnotation(ExcelTarget.class);
String targetId = etarget == null ? null : etarget.value();
getAllExcelField(entity.getExclusions(), targetId, fileds, excelParams, pojoClass, null);
//update-begin-author:taoyan date:20200304 for:在此方法循环内设置一下图片磁盘目录,便于导出
reConfigExcelExportParams(excelParams,entity);
//update-end-author:taoyan date:20200304 for:在此方法循环内设置一下图片磁盘目录,便于导出
int index = entity.isCreateHeadRows() ? createHeaderAndTitle(entity, sheet, workbook, excelParams) : 0;
int titleHeight = index;
setCellWith(excelParams, sheet);
//update-begin-author:liusq date:20210723 for:设置隐藏列
setColumnHidden(excelParams, sheet);
//update-end-author:liusq date:20210723 for:设置隐藏列
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,exportFields);
}
} catch (Exception e) {
LOGGER.error(e.getMessage(), e);
throw new ExcelExportException(ExcelExportEnum.EXPORT_ERROR, e.getCause());
}
}
public void createSheetForMap(Workbook workbook, ExportParams entity, List<ExcelExportEntity> entityList, Collection<? extends Map<?, ?>> dataSet) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Excel version is {}", entity.getType().equals(ExcelType.HSSF) ? "03" : "07");
}
if (workbook == null || entity == null || entityList == null || dataSet == null) {
throw new ExcelExportException(ExcelExportEnum.PARAMETER_ERROR);
}
super.type = entity.getType();
if (type.equals(ExcelType.XSSF)) {
MAX_NUM = 1000000;
}
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);
//update-begin-author:liusq date:20210723 for:设置隐藏列
setColumnHidden(excelParams, sheet);
//update-end-author:liusq date:20210723 for:设置隐藏列
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) {
LOGGER.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);
//update-begin-author:taoyan date:20200319 for:建议autoPoi升级优化数据返回List Map格式下的复合表头导出excel的体验 #873
if(entity.isColspan()){
List<String> subList = entity.getSubColumnList();
if(subList==null || subList.size()==0){
continue;
}else{
entity.initSubExportEntity(excelParams);
}
}
//update-end-author:taoyan date:20200319 for:建议autoPoi升级优化数据返回List Map格式下的复合表头导出excel的体验 #873
if (StringUtils.isNotBlank(entity.getName())) {
createStringCell(row, cellIndex, entity.getName(), titleStyle, entity);
}
if (entity.getList() != null) {
List<ExcelExportEntity> sTitel = entity.getList();
//update-begin-author:wangshuai date:20201118 for:一对多导出needMerge 子表数据对应数量小于2时报错 github#1840、gitee I1YH6B
if (StringUtils.isNotBlank(entity.getName())) {
try {
sheet.addMergedRegion(new CellRangeAddress(index, index, cellIndex, cellIndex + sTitel.size() - 1));
}catch (IllegalArgumentException e){
LOGGER.error("合并单元格错误日志:"+e.getMessage());
e.fillInStackTrace();
}
//update-end-author:wangshuai date:20201118 for:一对多导出needMerge 子表数据对应数量小于2时报错 github#1840、gitee I1YH6B
}
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);
//update-begin-author:wangshuai date:20201118 for:一对多导出needMerge 子表数据对应数量小于2时报错 github#1840、gitee I1YH6B
try{
sheet.addMergedRegion(new CellRangeAddress(index, index + 1, cellIndex, cellIndex));
}catch (IllegalArgumentException e){
LOGGER.error("合并单元格错误日志:"+e.getMessage());
e.fillInStackTrace();
}
//update-end-author:wangshuai date:20201118 for:一对多导出needMerge 子表数据对应数量小于2时报错 github#1840、gitee I1YH6B
}
cellIndex++;
}
return rows;
}
/**
* 判断表头是只有一行还是两行
*
* @param excelParams
* @return
*/
private int getRowNums(List<ExcelExportEntity> excelParams) {
for (int i = 0; i < excelParams.size(); i++) {
//update-begin-author:taoyan date:20200319 for:建议autoPoi升级优化数据返回List Map格式下的复合表头导出excel的体验 #873
ExcelExportEntity temp = excelParams.get(i);
if ((temp.getList() != null || temp.isColspan()) && StringUtils.isNotBlank(temp.getName())) {
return 2;
}
//update-end-author:taoyan date:20200319 for:建议autoPoi升级优化数据返回List Map格式下的复合表头导出excel的体验 #873
}
return 1;
}
protected 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;
}
//update-begin---author:liusq Date:20211217 for[LOWCOD-2521]【autopoi】大数据导出方法【全局】----
/**
* 添加数据到sheet
* @param workbook
* @param entity 导出参数
* @param entityList
* @param dataSet 导出数据
* @param sheet
* @date 2022年1月4号
*/
protected void insertDataToSheet(Workbook workbook, ExportParams entity,
List<ExcelExportEntity> entityList,Collection<? extends Map<?, ?>> dataSet,
Sheet sheet) {
try {
dataHanlder = entity.getDataHanlder();
if (dataHanlder != null && dataHanlder.getNeedHandlerFields() != null) {
needHanlderList = Arrays.asList(dataHanlder.getNeedHandlerFields());
}
// 创建表格样式
setExcelExportStyler((IExcelExportStyler) entity.getStyle()
.getConstructor(Workbook.class).newInstance(workbook));
Drawing patriarch = PoiExcelGraphDataUtil.getDrawingPatriarch(sheet);
List<ExcelExportEntity> excelParams = new ArrayList<ExcelExportEntity>();
if (entity.isAddIndex()) {
excelParams.add(indexExcelEntity(entity));
}
excelParams.addAll(entityList);
sortAllParams(excelParams);
int index = entity.isCreateHeadRows()
? createHeaderAndTitle(entity, sheet, workbook, excelParams) : 0;
int titleHeight = index;
setCellWith(excelParams, sheet);
setColumnHidden(excelParams, sheet);
short rowHeight = entity.getHeight() != 0 ? entity.getHeight() : getRowHeight(excelParams);
setCurrentIndex(1);
Iterator<?> its = dataSet.iterator();
List<Object> tempList = new ArrayList<Object>();
while (its.hasNext()) {
Object t = its.next();
index += createCells(patriarch, index, t, excelParams, sheet, workbook, rowHeight, 0)[0];
tempList.add(t);
if (index >= MAX_NUM) {
break;
}
}
if (entity.getFreezeCol() != 0) {
sheet.createFreezePane(entity.getFreezeCol(), 0, entity.getFreezeCol(), 0);
}
mergeCells(sheet, excelParams, titleHeight);
its = dataSet.iterator();
for (int i = 0, le = tempList.size(); i < le; i++) {
its.next();
its.remove();
}
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("List data more than max ,data size is {}",
dataSet.size());
}
// 发现还有剩余list 继续循环创建Sheet
if (dataSet.size() > 0) {
createSheetForMap(workbook, entity, entityList, dataSet);
} else {
// 创建合计信息
addStatisticsRow(getExcelExportStyler().getStyles(true, null), sheet);
}
} catch (Exception e) {
LOGGER.error(e.getMessage(), e);
throw new ExcelExportException(ExcelExportEnum.EXPORT_ERROR, e.getCause());
}
}
//update-end---author:liusq Date:20211217 for[LOWCOD-2521]【autopoi】大数据导出方法【全局】----
}

View File

@@ -0,0 +1,768 @@
/**
* Copyright 2013-2015 JEECG (jeecgos@163.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jeecgframework.poi.excel.export.base;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
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 org.jeecgframework.poi.excel.ExcelImportUtil;
import org.jeecgframework.poi.excel.entity.enmus.ExcelType;
import org.jeecgframework.poi.excel.entity.params.ExcelExportEntity;
import org.jeecgframework.poi.excel.entity.vo.PoiBaseConstants;
import org.jeecgframework.poi.excel.export.styler.IExcelExportStyler;
import org.jeecgframework.poi.exception.excel.ExcelExportException;
import org.jeecgframework.poi.exception.excel.enums.ExcelExportEnum;
import org.jeecgframework.poi.util.MyX509TrustManager;
import org.jeecgframework.poi.util.PoiMergeCellUtil;
import org.jeecgframework.poi.util.PoiPublicUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.imageio.ImageIO;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.SecureRandom;
import java.text.DecimalFormat;
import java.util.*;
/**
* 提供POI基础操作服务
*
* @author JEECG
* @date 2014年6月17日 下午6:15:13
*/
public abstract class ExcelExportBase extends ExportBase {
private static final Logger LOGGER = LoggerFactory.getLogger(ExcelExportBase.class);
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");
//update-begin-author:liusq---date:20220527--for: 修改成protected列循环时继承类需要用到 ---
protected IExcelExportStyler excelExportStyler;
//update-end-author:liusq---date:20220527--for: 修改成protected列循环时继承类需要用到 ---
/**
* 创建 最主要的 Cells
*
* @param styles
* @param rowHeight
* @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);
DataFormat df = workbook.createDataFormat();
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);
//update-begin-author:taoyan date:20200319 for:建议autoPoi升级优化数据返回List Map格式下的复合表头导出excel的体验 #873
if(entity.isSubColumn()){
continue;
}
if(entity.isMergeColumn()){
Map<String,Object> subColumnMap = new HashMap<>();
List<String> mapKeys = entity.getSubColumnList();
for (String subKey : mapKeys) {
Object subKeyValue = null;
if (t instanceof Map) {
subKeyValue = ((Map<?, ?>) t).get(subKey);
}else{
subKeyValue = PoiPublicUtil.getParamsValue(subKey,t);
}
subColumnMap.put(subKey,subKeyValue);
}
createListCells(patriarch, index, cellNum, subColumnMap, entity.getList(), sheet, workbook);
cellNum += entity.getSubColumnList().size();
//update-end-author:taoyan date:20200319 for:建议autoPoi升级优化数据返回List Map格式下的复合表头导出excel的体验 #873
} else 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);
//update-begin--Author:xuelin Date:20171018 forTASK #2372 【excel】AutoPoi 导出类型type增加数字类型--------------------
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(), getNumberCellStyle(index, df, entity), entity);
} else {
createImageCell(patriarch, entity, row, cellNum++, value == null ? "" : value.toString(), t);
}
//update-end--Author:xuelin Date:20171018 forTASK #2372 【excel】AutoPoi 导出类型type增加数字类型--------------------
//update-begin-author:liusq---date:20220728--for:[issues/I5I840] @Excel注解中不支持超链接但文档中支持 ---
if (entity.isHyperlink()) {
row.getCell(cellNum - 1)
.setHyperlink(dataHanlder.getHyperlink(
row.getSheet().getWorkbook().getCreationHelper(), t,
entity.getName(), value));
}
//update-end-author:liusq---date:20220728--for:[issues/I5I840] @Excel注解中不支持超链接但文档中支持 ---
}
}
// 合并需要合并的单元格
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));
}
//update-begin-author:wangshuai date:20201116 for:一对多导出needMerge 子表数据对应数量小于2时报错 github#1840、gitee I1YH6B
try {
if (maxHeight > 1) {
sheet.addMergedRegion(new CellRangeAddress(index, index + maxHeight - 1, cellNum, cellNum));
}
}catch (IllegalArgumentException e){
LOGGER.error("合并单元格错误日志:"+e.getMessage());
e.fillInStackTrace();
}
//update-end-author:wangshuai date:20201116 for:一对多导出needMerge 子表数据对应数量小于2时报错 github#1840、gitee I1YH6B
cellNum++;
}
}
return maxHeight;
}
/**
* 获取数值单元格样式
* @param index
* @param df
* @param entity
* @return
*/
private CellStyle getNumberCellStyle(int index,DataFormat df, ExcelExportEntity entity) {
//update-begin-author:liusq---date:2023-12-07--for: [issues/5538]导出表格设置了数字格式导出之后仍然是文本格式,并且无法进行计算
CellStyle cellStyle = index % 2 == 0 ? getStyles(false, entity) : getStyles(true, entity);
String numFormat = StringUtils.isNotBlank(entity.getNumFormat())? entity.getNumFormat():"0.00_ ";
cellStyle.setDataFormat(df.getFormat(numFormat));
return cellStyle;
//update-end-author:liusq---date:2023-12-07--for:[issues/5538]导出表格设置了数字格式导出之后仍然是文本格式,并且无法进行计算
}
/**
* 通过https地址获取图片数据
* @param imagePath
* @return
* @throws Exception
*/
private byte[] getImageDataByHttps(String imagePath) throws Exception {
SSLContext sslcontext = SSLContext.getInstance("SSL","SunJSSE");
sslcontext.init(null, new TrustManager[]{new MyX509TrustManager()}, new SecureRandom());
URL url = new URL(imagePath);
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setSSLSocketFactory(sslcontext.getSocketFactory());
conn.setRequestMethod("GET");
conn.setConnectTimeout(5 * 1000);
InputStream inStream = conn.getInputStream();
byte[] value = readInputStream(inStream);
return value;
}
/**
* 通过http地址获取图片数据
* @param imagePath
* @return
* @throws Exception
*/
private byte[] getImageDataByHttp(String imagePath) throws Exception {
URL url = new URL(imagePath);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(5 * 1000);
InputStream inStream = conn.getInputStream();
byte[] value = readInputStream(inStream);
return value;
}
/**
* 图片类型的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;
}
//update-beign-author:taoyan date:20200302 for:【多任务】online 专项集中问题 LOWCOD-159
int imageType = entity.getExportImageType();
byte[] value = null;
if(imageType == 2){
//原来逻辑 2
value = (byte[]) (entity.getMethods() != null ? getFieldBySomeMethod(entity.getMethods(), obj) : entity.getMethod().invoke(obj, new Object[] {}));
} else if(imageType==4 || imagePath.startsWith("http")){
//新增逻辑 网络图片4
try {
if (imagePath.indexOf(",") != -1) {
if(imagePath.startsWith(",")){
imagePath = imagePath.substring(1);
}
String[] images = imagePath.split(",");
imagePath = images[0];
}
if(imagePath.startsWith("https")){
value = getImageDataByHttps(imagePath);
}else{
value = getImageDataByHttp(imagePath);
}
} catch (Exception exception) {
LOGGER.warn(exception.getMessage());
//exception.printStackTrace();
}
} else {
ByteArrayOutputStream byteArrayOut = new ByteArrayOutputStream();
BufferedImage bufferImg;
String path = null;
if(imageType == 1){
//原来逻辑 1
path = PoiPublicUtil.getWebRootPath(imagePath);
LOGGER.debug("--- createImageCell getWebRootPath ----filePath--- "+ path);
path = path.replace("WEB-INF/classes/", "");
path = path.replace("file:/", "");
}else if(imageType==3){
//新增逻辑 本地图片3
//begin-------authorliusq---data2021-01-27----for本地图片ImageBasePath为空报错的问题
if(StringUtils.isNotBlank(entity.getImageBasePath())){
if(!entity.getImageBasePath().endsWith(File.separator) && !imagePath.startsWith(File.separator)){
path = entity.getImageBasePath()+File.separator+imagePath;
}else{
path = entity.getImageBasePath()+imagePath;
}
}else{
path = imagePath;
}
//end-------authorliusq---data2021-01-27----for本地图片ImageBasePath为空报错的问题
}
try {
bufferImg = ImageIO.read(new File(path));
//update-begin-author:taoYan date:20211203 for: Excel 导出图片的文件带小数点符号 导出报错 https://gitee.com/jeecg/jeecg-boot/issues/I4JNHR
ImageIO.write(bufferImg, imagePath.substring(imagePath.lastIndexOf(".") + 1, imagePath.length()), byteArrayOut);
//update-end-author:taoYan date:20211203 for: Excel 导出图片的文件带小数点符号 导出报错 https://gitee.com/jeecg/jeecg-boot/issues/I4JNHR
value = byteArrayOut.toByteArray();
} catch (Exception e) {
LOGGER.error(e.getMessage());
}
}
if (value != null) {
patriarch.createPicture(anchor, row.getSheet().getWorkbook().addPicture(value, getImageType(value)));
}
//update-end-author:taoyan date:20200302 for:【多任务】online 专项集中问题 LOWCOD-159
}
/**
* inStream读取到字节数组
* @param inStream
* @return
* @throws Exception
*/
private byte[] readInputStream(InputStream inStream) throws Exception {
if(inStream==null){
return null;
}
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len = 0;
//每次读取的字符串长度,如果为-1代表全部读取完毕
while ((len = inStream.read(buffer)) != -1) {
outStream.write(buffer, 0, len);
}
inStream.close();
return outStream.toByteArray();
}
private int createIndexCell(Row row, int index, ExcelExportEntity excelExportEntity) {
if (excelExportEntity.getName().equals("序号") && PoiBaseConstants.IS_ADD_INDEX.equals(excelExportEntity.getFormat())) {
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;
DataFormat df = workbook.createDataFormat();
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);
//update-begin--Author:xuelin Date:20171018 forTASK #2372 【excel】AutoPoi 导出类型type增加数字类型--------------------
if (entity.getType() == 1) {
createStringCell(row, cellNum++, value == null ? "" : value.toString(), row.getRowNum() % 2 == 0 ? getStyles(false, entity) : getStyles(true, entity), entity);
//update-begin-author:liusq---date:20220728--for: 新增isHyperlink属性 ---
if (entity.isHyperlink()) {
row.getCell(cellNum - 1)
.setHyperlink(dataHanlder.getHyperlink(
row.getSheet().getWorkbook().getCreationHelper(), obj, entity.getName(),
value));
}
//update-end-author:liusq---date:20220728--for: 新增isHyperlink属性 ---
} else if (entity.getType() == 4){
createNumericCell(row, cellNum++, value == null ? "" : value.toString(), getNumberCellStyle(index, df, entity), entity);
//update-begin-author:liusq---date:20220728--for: 新增isHyperlink属性 ---
if (entity.isHyperlink()) {
row.getCell(cellNum - 1)
.setHyperlink(dataHanlder.getHyperlink(
row.getSheet().getWorkbook().getCreationHelper(), obj, entity.getName(),
value));
}
//update-end-author:liusq---date:20220728--for: 新增isHyperlink属性 ---
} else{
createImageCell(patriarch, entity, row, cellNum++, value == null ? "" : value.toString(), obj);
}
//update-end--Author:xuelin Date:20171018 forTASK #2372 【excel】AutoPoi 导出类型type增加数字类型--------------------
}
}
//update-begin--Author:xuelin Date:20171018 forTASK #2372 【excel】AutoPoi 导出类型type增加数字类型--------------------
public void createNumericCell (Row row, int index, String text, CellStyle style, ExcelExportEntity entity) {
Cell cell = row.createCell(index);
if (style != null) {
cell.setCellStyle(style);
}
if(StringUtils.isEmpty(text)){
cell.setCellValue("");
cell.setCellType(CellType.BLANK);
}else{
cell.setCellValue(Double.parseDouble(text));
cell.setCellType(CellType.NUMERIC);
}
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(CellType.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 row
* @param index
* @param text
* @param style
* @param entity
* @param workbook
*/
/*public void createStringCell(Row row, int index, String text, CellStyle style, ExcelExportEntity entity, Workbook workbook) {
Cell cell = row.createCell(index);
if (style != null && style.getDataFormat() > 0 && style.getDataFormat() < 12) {
cell.setCellValue(Double.parseDouble(text));
cell.setCellType(CellType.NUMERIC);
}else{
RichTextString Rtext;
if (type.equals(ExcelType.HSSF)) {
Rtext = new HSSFRichTextString(text);
} else {
Rtext = new XSSFRichTextString(text);
}
cell.setCellValue(Rtext);
}
if (style != null) {
Font font = workbook.createFont();
font.setUnderline(Font.U_SINGLE);
style.setFont(font);
cell.setCellStyle(style);
}
addStatisticsData(index, text, entity);
}*/
//update-end--Author:xuelin Date:20171018 forTASK #2372 【excel】AutoPoi 导出类型type增加数字类型----------------------
/**
* 创建统计行
*
* @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) {
//update-begin---author:liusq Date:20200909 forAutoPoi多表头导出会多出一列空白列 #1513------------
if(entity.getGroupName()!=null){
continue;
}else if (entity.getSubColumnList()!=null&&entity.getSubColumnList().size()>0){
length += entity.getSubColumnList().size();
}else{
length += entity.getList() != null ? entity.getList().size() : 1;
}
//update-end---author:liusq Date:20200909 forAutoPoi多表头导出会多出一列空白列 #1513------------
}
return length;
}
/**
* 获取图片类型,设置图片插入类型
*
* @param value
* @return
* @Author JEECG
* @date 2013年11月25日
*/
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++;
}
}
}
/**
* 设置隐藏列
* @param excelParams
* @param sheet
*/
public void setColumnHidden(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.setColumnHidden(index, list.get(j).isColumnHidden());
index++;
}
} else {
sheet.setColumnHidden(index, excelParams.get(i).isColumnHidden());
index++;
}
}
}
public void setCurrentIndex(int currentIndex) {
this.currentIndex = currentIndex;
}
public void setExcelExportStyler(IExcelExportStyler excelExportStyler) {
this.excelExportStyler = excelExportStyler;
}
public IExcelExportStyler getExcelExportStyler() {
return excelExportStyler;
}
//update-begin---author:liusq Date:20211217 for[LOWCOD-2521]【autopoi】大数据导出方法【全局】----
/**
*创建单元格,返回最大高度和单元格数
* @param patriarch
* @param index
* @param t
* @param excelParams
* @param sheet
* @param workbook
* @param rowHeight 行高
* @param cellNum 格数
* @return
*/
public int[] createCells(Drawing patriarch, int index, Object t,
List<ExcelExportEntity> excelParams, Sheet sheet, Workbook workbook,
short rowHeight, int cellNum) {
try {
ExcelExportEntity entity;
Row row = sheet.getRow(index) == null ? sheet.createRow(index) : sheet.getRow(index);
DataFormat df = workbook.createDataFormat();
if (rowHeight != -1) {
row.setHeight(rowHeight);
}
int maxHeight = 1, listMaxHeight = 1;
// 合并需要合并的单元格
int margeCellNum = cellNum;
int indexKey = 0;
if (excelParams != null && !excelParams.isEmpty()) {
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 tmpListHeight = 0;
if (list != null && list.size() > 0) {
int tempCellNum = 0;
for (Object obj : list) {
int[] temp = createCells(patriarch, index + tmpListHeight, obj, entity.getList(), sheet, workbook, rowHeight, cellNum);
tempCellNum = temp[1];
tmpListHeight += temp[0];
}
cellNum = tempCellNum;
listMaxHeight = Math.max(listMaxHeight, tmpListHeight);
} else {
cellNum = cellNum + getListCellSize(entity.getList());
}
} 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(),
getNumberCellStyle(index, df, entity),
entity);
} else {
createImageCell(patriarch, entity, row, cellNum++,
value == null ? "" : value.toString(), t);
}
//update-begin-author:liusq---date:20220728--for: 新增isHyperlink属性 ---
if (entity.isHyperlink()) {
row.getCell(cellNum - 1)
.setHyperlink(dataHanlder.getHyperlink(
row.getSheet().getWorkbook().getCreationHelper(), t,
entity.getName(), value));
}
//update-end-author:liusq---date:20220728--for: 新增isHyperlink属性 ---
}
}
maxHeight += listMaxHeight - 1;
if (indexKey == 1 && excelParams.get(1).isNeedMerge()) {
excelParams.get(0).setNeedMerge(true);
}
for (int k = indexKey, paramSize = excelParams.size(); k < paramSize; k++) {
entity = excelParams.get(k);
if (entity.getList() != null) {
margeCellNum += entity.getList().size();
} else if (entity.isNeedMerge() && maxHeight > 1) {
for (int i = index + 1; i < index + maxHeight; i++) {
if (sheet.getRow(i) == null) {
sheet.createRow(i);
}
sheet.getRow(i).createCell(margeCellNum);
sheet.getRow(i).getCell(margeCellNum).setCellStyle(getStyles(false, entity));
}
PoiMergeCellUtil.addMergedRegion(sheet, index, index + maxHeight - 1, margeCellNum, margeCellNum);
margeCellNum++;
}
}
return new int[]{maxHeight, cellNum};
} catch (Exception e) {
LOGGER.error("excel cell export error ,data is :{}", ReflectionToStringBuilder.toString(t));
LOGGER.error(e.getMessage(), e);
throw new ExcelExportException(ExcelExportEnum.EXPORT_ERROR, e);
}
}
/**
* 获取集合的宽度
*
* @param list
* @return
*/
protected int getListCellSize(List<ExcelExportEntity> list) {
int cellSize = 0;
for (ExcelExportEntity ee : list) {
if (ee.getList() != null) {
cellSize += getListCellSize(ee.getList());
} else {
cellSize++;
}
}
return cellSize;
}
//update-end---author:liusq Date:20211217 for[LOWCOD-2521]【autopoi】大数据导出方法【全局】----
}

View File

@@ -0,0 +1,552 @@
/**
* Copyright 2013-2015 JEECG (jeecgos@163.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jeecgframework.poi.excel.export.base;
import org.apache.commons.lang3.StringUtils;
import org.jeecgframework.core.util.ApplicationContextUtil;
import org.jeecgframework.dict.service.AutoPoiDictServiceI;
import org.jeecgframework.poi.excel.annotation.*;
import org.jeecgframework.poi.excel.entity.ExportParams;
import org.jeecgframework.poi.excel.entity.params.ExcelExportEntity;
import org.jeecgframework.poi.handler.inter.IExcelDataHandler;
import org.jeecgframework.poi.handler.inter.IExcelDictHandler;
import org.jeecgframework.poi.util.PoiPublicUtil;
import java.lang.reflect.*;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
/**
* 导出基础处理,不设计POI,只设计对象,保证复用性
*
* @author JEECG
* @date 2014年8月9日 下午11:01:32
*/
public class ExportBase {
protected IExcelDataHandler dataHanlder;
//update-begin-author:liusq---date:20220527--for: 增加列循环功能时中用到 ---
protected IExcelDictHandler dictHandler;
//update-end-author:liusq---date:20220527--for: be 增加列循环功能时中用到---
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;
//update-begin-author:wangshuai date:20201118 for:Excel导出错误原因value为""字符串gitee I249JF
if ("".equals(value)) {
value = null;
}
//update-begin-author:wangshuai date:20201118 for:Excel导出错误原因value为""字符串gitee I249JF
if (value instanceof String && entity.getDatabaseFormat() != null) {
SimpleDateFormat format = new SimpleDateFormat(entity.getDatabaseFormat());
temp = format.parse(value.toString());
} else if (value instanceof Date) {
temp = (Date) value;
//update-begin-author:taoyan date:2022-5-17 for: mybatis-plus升级 时间字段变成了jdk8的LocalDateTime导致格式化失败
} else if (value instanceof LocalDateTime) {
LocalDateTime ldt = (LocalDateTime) value;
DateTimeFormatter format = DateTimeFormatter.ofPattern(entity.getFormat());
return format.format(ldt);
} else if (value instanceof LocalDate) {
LocalDate ld = (LocalDate) value;
DateTimeFormatter format = DateTimeFormatter.ofPattern(entity.getFormat());
return format.format(ld);
}
//update-end-author:taoyan date:2022-5-17 for: mybatis-plus升级 时间字段变成了jdk8的LocalDateTime导致格式化失败
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);
//update-begin-author:taoyan date:20210531 for:excel导出支持 注解@ExcelEntity显示合并表头
if (excel.show() == true) {
List<ExcelExportEntity> list = new ArrayList<ExcelExportEntity>();
// 这里有个设计的坑导出的时候最后一个参数是null, 即getgetMethods获取的是空导入的时候需要设置层级getmethod
getAllExcelField(exclusions, StringUtils.isNotEmpty(excel.id()) ? excel.id() : targetId,
PoiPublicUtil.getClassFields(field.getType()), list, field.getType(), null);
excelEntity = new ExcelExportEntity();
excelEntity.setName(getExcelName(excel.name(), targetId));
excelEntity.setMethod(PoiPublicUtil.getMethod(field.getName(), pojoClass));
excelEntity.setList(list);
excelParams.add(excelEntity);
} else {
getAllExcelField(exclusions, StringUtils.isNotEmpty(excel.id()) ? excel.id() : targetId,
PoiPublicUtil.getClassFields(field.getType()), excelParams, field.getType(), newMethods);
}
//update-end-author:taoyan date:20210531 for:excel导出支持 注解@ExcelEntity显示合并表头
}
}
}
/**
* 获取这个字段的顺序
*
* @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 {
if (Objects.isNull(obj)) {
return "";
}
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[] {});
}
//update-begin-author:scott date:20200831 for:导出excel实体反射时间格式转换错误 #1573
value = Optional.ofNullable(value).orElse("");
if (StringUtils.isEmpty(value.toString())) {
return "";
}
//update-end-author:scott date:20200831 for:导出excel实体反射时间格式转换错误 #1573
//update-begin-author:taoyan date:2020319 for:Excel注解的numFormat方法似乎未实现 #970
if (StringUtils.isNotEmpty(entity.getNumFormat()) && value != null) {
value = new DecimalFormat(entity.getNumFormat()).format(value);
}
//update-end-author:taoyan date:2020319 for:Excel注解的numFormat方法似乎未实现 #970
if (StringUtils.isNotEmpty(entity.getDict()) && dictHandler != null) {
value = dictHandler.toName(entity.getDict(), obj, entity.getName(), value);
}
if (StringUtils.isNotEmpty(entity.getFormat())) {
value = formatValue(value, entity);
}
if (entity.getReplace() != null && entity.getReplace().length > 0) {
//update-begin-author:taoyan date20180731 for:TASK #3038 【bug】Excel 导出多个值逗号隔开的情况下导出字典值是ID值
if (value == null) {
value = "";//String.valueOf(value) 如果value为null 则返回"null"
}
String oldVal = value.toString();
if (entity.isMultiReplace()) {
value = multiReplaceValue(entity.getReplace(), String.valueOf(value));
} else {
value = replaceValue(entity.getReplace(), String.valueOf(value));
}
//update-end-author:taoyan date20180731 for:TASK #3038 【bug】Excel 导出多个值逗号隔开的情况下导出字典值是ID值
//update-begin-author:liusq date20210127 for: 两个数值相等,就证明处理翻译失败的情况
if (oldVal.equals(value)) {
}
//update-end-author:liusq date20210127 for: 两个数值相等,就证明处理翻译失败的情况
}
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 = entity.getMethod().invoke(obj, new Object[] {});
if (value instanceof Collection) {
return (Collection<?>) value;
} else {
List list = new ArrayList();
list.add(value);
return list;
}
}
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());
excelEntity.setHyperlink(excel.isHyperlink());
if (StringUtils.isNotEmpty(excel.dicCode())) {
AutoPoiDictServiceI jeecgDictService = null;
try {
jeecgDictService = ApplicationContextUtil.getContext().getBean(AutoPoiDictServiceI.class);
} catch (Exception e) {
}
if (jeecgDictService != null) {
String[] dictReplace = jeecgDictService.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();
//update-begin-author:taoyan date:20200319 for:autopoi 双表头问题 #862 基于注解的解决方案
excelEntity.setKey(fieldname);
//update-end-author:taoyan date:20200319 for:autopoi 双表头问题 #862 基于注解的解决方案
//update-begin-author:taoyan date:20200319 for:Excel注解的numFormat方法似乎未实现 #970
excelEntity.setNumFormat(excel.numFormat());
//update-end-author:taoyan date:20200319 for:Excel注解的numFormat方法似乎未实现 #970
//update-begin-author:liusq date:202010723 for:Excel注解的isColumnHidden方法未实现
excelEntity.setColumnHidden(excel.isColumnHidden());
//update-end-author:liusq date:202010723 for:Excel注解的isColumnHidden方法未实现
//update-begin-author:taoyan date:20180615 for:TASK #2798 【例子】导入扩展方法,支持自定义导入字段转换规则
excelEntity.setMethod(PoiPublicUtil.getMethod(fieldname, pojoClass, excel.exportConvert()));
//update-end-author:taoyan date:20180615 for:TASK #2798 【例子】导入扩展方法,支持自定义导入字段转换规则
//update-begin-author:taoyan date:20180801 for:TASK #3038 【bug】Excel 导出多个值逗号隔开的情况下导出字典值是ID值
excelEntity.setMultiReplace(excel.multiReplace());
//update-end-author:taoyan date:20180801 for:TASK #3038 【bug】Excel 导出多个值逗号隔开的情况下导出字典值是ID值
//update-begin-author:taoyan date:20200319 for:autopoi 双表头问题 #862 基于实体注解的解决方案
if (StringUtils.isNotEmpty(excel.groupName())) {
excelEntity.setGroupName(excel.groupName());
excelEntity.setColspan(true);
}
//update-end-author:taoyan date:20200319 for:autopoi 双表头问题 #862 基于实体注解的解决方案
}
/**
* 判断在这个单元格显示的名称
*
* @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("_"); {'男_sheng_1','女_2'}
//update-begin-author:liusq date20210127 for:字符串截取修改
temp = getValueArr(str);
//update-end-author:liusq date20210127 for:字符串截取修改
//update-begin---author:scott Date:20211220 for[issues/I4MBB3]@Excel dicText字段的值有下划线时导入功能不能正确解析---
if (value.equals(temp[1]) || value.replace("_", "---").equals(temp[1])) {
value = temp[0];
break;
}
//update-end---author:scott Date:20211220 for[issues/I4MBB3]@Excel dicText字段的值有下划线时导入功能不能正确解析---
}
return value;
}
//update-begin-author:taoyan date20180731 for:TASK #3038 【bug】Excel 导出多个值逗号隔开的情况下导出字典值是ID值
/**
* 如果需要被替换的值是多选项,则每一项之间有逗号隔开,走以下方法
* @author taoYan
* @since 2018年7月31日
*/
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("_");
//update-begin-author:liusq date20210127 for:字符串截取修改
temp = getValueArr(str);
//update-end-author:liusq date20210127 for:字符串截取修改
//update-begin---author:scott Date:20211220 for[issues/I4MBB3]@Excel dicText字段的值有下划线时导入功能不能正确解析---
if (radio.equals(temp[1]) || radio.replace("_", "---").equals(temp[1])) {
result = result.concat(temp[0]) + ",";
break;
}
//update-end---author:scott Date:20211220 for[issues/I4MBB3]@Excel dicText字段的值有下划线时导入功能不能正确解析---
}
}
if (result.equals("")) {
result = value;
} else {
result = result.substring(0, result.length() - 1);
}
return result;
} else {
return replaceValue(replace, value);
}
}
//update-end-author:taoyan date20180731 for:TASK #3038 【bug】Excel 导出多个值逗号隔开的情况下导出字典值是ID值
/**
* 对字段根据用户设置排序
*/
public void sortAllParams(List<ExcelExportEntity> excelParams) {
Collections.sort(excelParams);
for (ExcelExportEntity entity : excelParams) {
if (entity.getList() != null) {
Collections.sort(entity.getList());
}
}
}
/**
* 循环ExcelExportEntity集合 附加配置信息<br>
* 1.列排序<br>
* 2.读取图片根路径设置(如果有字段是图片类型 并且存储在本地 则设置磁盘路径获取全地址导出)<br>
* 3.多表头配置(仅限于单表 会走这个逻辑处理)
*/
public void reConfigExcelExportParams(List<ExcelExportEntity> excelParams, ExportParams exportParams) {
Set<String> NameSet = new HashSet<String>();
Map<String, List<String>> groupAndColumnList = new HashMap<String, List<String>>();
Map<String, Integer> groupOrder = new HashMap<>();
int index = -99;
for (ExcelExportEntity entity : excelParams) {
if (entity.getOrderNum() == 0) {
entity.setOrderNum(index++);
}
if (entity.getExportImageType() == 3) {
entity.setImageBasePath(exportParams.getImageBasePath());
}
if (entity.getList() != null) {
Collections.sort(entity.getList());
}
String groupName = entity.getGroupName();
if (StringUtils.isNotEmpty(groupName)) {
List<String> ls = groupAndColumnList.get(groupName);
if (ls == null) {
ls = new ArrayList<String>();
groupAndColumnList.put(groupName, ls);
}
ls.add(entity.getKey().toString());
Integer order = groupOrder.get(groupName);
if (order == null || entity.getOrderNum() < order) {
order = entity.getOrderNum();
}
groupOrder.put(groupName, order);
}
}
for (String key : groupAndColumnList.keySet()) {
ExcelExportEntity temp = new ExcelExportEntity(key);
temp.setColspan(true);
temp.setSubColumnList(groupAndColumnList.get(key));
temp.setOrderNum(groupOrder.get(key));
excelParams.add(temp);
}
Collections.sort(excelParams);
}
/**
* 字典文本中含多个下划线横岗,取最后一个(解决空值情况)
*
* @param val
* @return
*/
public String[] getValueArr(String val) {
int i = val.lastIndexOf("_");//最后一个分隔符的位置
String[] c = new String[2];
c[0] = val.substring(0, i); //label
c[1] = val.substring(i + 1); //key
return c;
}
}

View File

@@ -0,0 +1,83 @@
/**
* Copyright 2013-2015 JEECG (jeecgos@163.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jeecgframework.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 org.jeecgframework.poi.excel.entity.params.ExcelExportEntity;
import org.jeecgframework.poi.excel.entity.params.ExcelForEachParams;
/**
* 抽象接口提供两个公共方法
*
* @author JEECG
* @date 2015年1月9日 下午5:48:55
*/
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;
}
/**
* 获取模板样式(列循环时用到)
* @param isSingle
* @param excelForEachParams
* @return
*/
@Override
public CellStyle getTemplateStyles(boolean isSingle, ExcelForEachParams excelForEachParams) {
return null;
}
}

View File

@@ -0,0 +1,81 @@
/**
* Copyright 2013-2015 JEECG (jeecgos@163.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jeecgframework.poi.excel.export.styler;
import org.apache.poi.ss.usermodel.*;
/**
* 带有边框的Excel样式
*
* @author JEECG
* @date 2015年1月9日 下午5:55:29
*/
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(BorderStyle.THIN); // 左边框
titleStyle.setBorderRight(BorderStyle.THIN); // 右边框
titleStyle.setBorderBottom(BorderStyle.THIN);
titleStyle.setBorderTop(BorderStyle.THIN);
titleStyle.setAlignment(HorizontalAlignment.CENTER);
titleStyle.setVerticalAlignment(VerticalAlignment.CENTER);
return titleStyle;
}
@Override
public CellStyle stringNoneStyle(Workbook workbook, boolean isWarp) {
CellStyle style = workbook.createCellStyle();
style.setBorderLeft(BorderStyle.THIN); // 左边框
style.setBorderRight(BorderStyle.THIN); // 右边框
style.setBorderBottom(BorderStyle.THIN);
style.setBorderTop(BorderStyle.THIN);
style.setAlignment(HorizontalAlignment.CENTER);
style.setVerticalAlignment(VerticalAlignment.CENTER);
style.setDataFormat(STRING_FORMAT);
if (isWarp) {
style.setWrapText(true);
}
return style;
}
@Override
public CellStyle getTitleStyle(short color) {
CellStyle titleStyle = workbook.createCellStyle();
titleStyle.setBorderLeft(BorderStyle.THIN); // 左边框
titleStyle.setBorderRight(BorderStyle.THIN); // 右边框
titleStyle.setBorderBottom(BorderStyle.THIN);
titleStyle.setBorderTop(BorderStyle.THIN);
titleStyle.setAlignment(HorizontalAlignment.CENTER);
titleStyle.setVerticalAlignment(VerticalAlignment.CENTER);
titleStyle.setWrapText(true);
return titleStyle;
}
@Override
public CellStyle stringSeptailStyle(Workbook workbook, boolean isWarp) {
return isWarp ? stringNoneWrapStyle : stringNoneStyle;
}
}

View File

@@ -0,0 +1,89 @@
/**
* Copyright 2013-2015 JEECG (jeecgos@163.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jeecgframework.poi.excel.export.styler;
import org.apache.poi.ss.usermodel.*;
/**
* 带有样式的导出服务
*
* @author JEECG
* @date 2015年1月9日 下午4:54:15
*/
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(HorizontalAlignment.CENTER);
titleStyle.setVerticalAlignment(VerticalAlignment.CENTER);
return titleStyle;
}
@Override
public CellStyle stringNoneStyle(Workbook workbook, boolean isWarp) {
CellStyle style = workbook.createCellStyle();
style.setBorderLeft(BorderStyle.THIN); // 左边框
style.setBorderRight(BorderStyle.THIN); // 右边框
style.setBorderBottom(BorderStyle.THIN);
style.setBorderTop(BorderStyle.THIN);
style.setAlignment(HorizontalAlignment.CENTER);
style.setVerticalAlignment(VerticalAlignment.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(HorizontalAlignment.CENTER);
titleStyle.setVerticalAlignment(VerticalAlignment.CENTER);
titleStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND); // 填充图案
titleStyle.setWrapText(true);
return titleStyle;
}
@Override
public CellStyle stringSeptailStyle(Workbook workbook, boolean isWarp) {
CellStyle style = workbook.createCellStyle();
style.setBorderLeft(BorderStyle.THIN); // 左边框
style.setBorderRight(BorderStyle.THIN); // 右边框
style.setBorderBottom(BorderStyle.THIN);
style.setBorderTop(BorderStyle.THIN);
style.setFillForegroundColor((short) 41); // 填充的背景颜色
style.setFillPattern(FillPatternType.SOLID_FOREGROUND); // 填充图案
style.setAlignment(HorizontalAlignment.CENTER);
style.setVerticalAlignment(VerticalAlignment.CENTER);
style.setDataFormat(STRING_FORMAT);
if (isWarp) {
style.setWrapText(true);
}
return style;
}
}

View File

@@ -0,0 +1,76 @@
/**
* Copyright 2013-2015 JEECG (jeecgos@163.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jeecgframework.poi.excel.export.styler;
import org.apache.poi.ss.usermodel.*;
/**
* 样式的默认实现
*
* @author JEECG
* @date 2015年1月9日 下午5:36:08
*/
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(HorizontalAlignment.CENTER);
titleStyle.setVerticalAlignment(VerticalAlignment.CENTER);
titleStyle.setWrapText(true);
return titleStyle;
}
@Override
public CellStyle stringSeptailStyle(Workbook workbook, boolean isWarp) {
CellStyle style = workbook.createCellStyle();
style.setAlignment( HorizontalAlignment.CENTER);
style.setVerticalAlignment(VerticalAlignment.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( HorizontalAlignment.CENTER);
titleStyle.setVerticalAlignment(VerticalAlignment.CENTER);
return titleStyle;
}
@Override
public CellStyle stringNoneStyle(Workbook workbook, boolean isWarp) {
CellStyle style = workbook.createCellStyle();
style.setAlignment(HorizontalAlignment.CENTER);
style.setVerticalAlignment(VerticalAlignment.CENTER);
style.setDataFormat(STRING_FORMAT);
if (isWarp) {
style.setWrapText(true);
}
return style;
}
}

View File

@@ -0,0 +1,59 @@
/**
* Copyright 2013-2015 JEECG (jeecgos@163.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jeecgframework.poi.excel.export.styler;
import org.apache.poi.ss.usermodel.CellStyle;
import org.jeecgframework.poi.excel.entity.params.ExcelExportEntity;
import org.jeecgframework.poi.excel.entity.params.ExcelForEachParams;
/**
* Excel导出样式接口
*
* @author JEECG
* @date 2015年1月9日 下午5:32:30
*/
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);
/**
* 模板使用的样式设置
*/
public CellStyle getTemplateStyles(boolean isSingle, ExcelForEachParams excelForEachParams);
}

View File

@@ -0,0 +1,263 @@
///**
// *
// */
//package org.jeecgframework.poi.excel.graph.builder;
//
//import java.util.ArrayList;
//import java.util.List;
//
//import org.apache.commons.lang3.StringUtils;
//import org.apache.poi.ss.usermodel.Chart;
//import org.apache.poi.ss.usermodel.ClientAnchor;
//import org.apache.poi.ss.usermodel.Drawing;
//import org.apache.poi.ss.usermodel.Sheet;
//import org.apache.poi.ss.usermodel.Workbook;
//import org.apache.poi.ss.usermodel.charts.AxisCrosses;
//import org.apache.poi.ss.usermodel.charts.AxisPosition;
//import org.apache.poi.ss.usermodel.charts.ChartAxis;
//import org.apache.poi.ss.usermodel.charts.ChartDataSource;
//import org.apache.poi.ss.usermodel.charts.ChartLegend;
//import org.apache.poi.ss.usermodel.charts.DataSources;
//import org.apache.poi.ss.usermodel.charts.LegendPosition;
//import org.apache.poi.ss.usermodel.charts.LineChartData;
//import org.apache.poi.ss.usermodel.charts.ScatterChartData;
//import org.apache.poi.ss.usermodel.charts.ValueAxis;
//import org.apache.poi.ss.util.CellRangeAddress;
//
//import org.jeecgframework.poi.excel.graph.constant.ExcelGraphElementType;
//import org.jeecgframework.poi.excel.graph.constant.ExcelGraphType;
//import org.jeecgframework.poi.excel.graph.entity.ExcelGraph;
//import org.jeecgframework.poi.excel.graph.entity.ExcelGraphElement;
//import org.jeecgframework.poi.excel.graph.entity.ExcelTitleCell;
//import org.jeecgframework.poi.util.PoiCellUtil;
//import org.jeecgframework.poi.util.PoiExcelGraphDataUtil;
//
///**
// * @Description
// * @author liusq
// * @data 2022年1月4号
// */
//public class ExcelChartBuildService
//{
// /**
// *
// * @param workbook
// * @param graphList
// * @param build 通过实时数据行来重新计算图形定义
// * @param append
// */
// public static void createExcelChart(Workbook workbook, List<ExcelGraph> graphList, Boolean build, Boolean append)
// {
// if(workbook!=null&&graphList!=null){
// //设定默认第一个sheet为数据项
// Sheet dataSouce=workbook.getSheetAt(0);
// if(dataSouce!=null){
// buildTitle(dataSouce,graphList);
//
// if(build){
// PoiExcelGraphDataUtil.buildGraphData(dataSouce, graphList);
// }
// if(append){
// buildExcelChart(dataSouce, dataSouce, graphList);
// }else{
// Sheet sheet=workbook.createSheet("图形界面");
// buildExcelChart(dataSouce, sheet, graphList);
// }
// }
//
// }
// }
//
// /**
// * 构建基础图形
// * @param drawing
// * @param anchor
// * @param dataSourceSheet
// * @param graph
// */
// private static void buildExcelChart(Drawing drawing,ClientAnchor anchor,Sheet dataSourceSheet,ExcelGraph graph){
// Chart chart = null;
// // TODO 图表没有成功
// //drawing.createChart(anchor);
// ChartLegend legend = chart.getOrCreateLegend();
// legend.setPosition(LegendPosition.TOP_RIGHT);
//
// ChartAxis bottomAxis = chart.getChartAxisFactory().createCategoryAxis(AxisPosition.BOTTOM);
// ValueAxis leftAxis = chart.getChartAxisFactory().createValueAxis(AxisPosition.LEFT);
// leftAxis.setCrosses(AxisCrosses.AUTO_ZERO);
// ExcelGraphElement categoryElement=graph.getCategory();
//
// ChartDataSource categoryChart;
// if(categoryElement!=null&& categoryElement.getElementType().equals(ExcelGraphElementType.STRING_TYPE)){
// categoryChart=DataSources.fromStringCellRange(dataSourceSheet, new CellRangeAddress(categoryElement.getStartRowNum(),categoryElement.getEndRowNum(),categoryElement.getStartColNum(),categoryElement.getEndColNum()));
// }else{
// categoryChart=DataSources.fromNumericCellRange(dataSourceSheet, new CellRangeAddress(categoryElement.getStartRowNum(),categoryElement.getEndRowNum(),categoryElement.getStartColNum(),categoryElement.getEndColNum()));
// }
//
// List<ExcelGraphElement> valueList=graph.getValueList();
// List<ChartDataSource<Number>> chartValueList= new ArrayList<>();
// if(valueList!=null&&valueList.size()>0){
// for(ExcelGraphElement ele:valueList){
// ChartDataSource<Number> source=DataSources.fromNumericCellRange(dataSourceSheet, new CellRangeAddress(ele.getStartRowNum(),ele.getEndRowNum(),ele.getStartColNum(),ele.getEndColNum()));
// chartValueList.add(source);
// }
// }
//
// if(graph.getGraphType().equals(ExcelGraphType.LINE_CHART)){
// LineChartData data = chart.getChartDataFactory().createLineChartData();
// buildLineChartData(data, categoryChart, chartValueList, graph.getTitle());
// chart.plot(data, bottomAxis, leftAxis);
// }
// else
// {
// ScatterChartData data=chart.getChartDataFactory().createScatterChartData();
// buildScatterChartData(data, categoryChart, chartValueList,graph.getTitle());
// chart.plot(data, bottomAxis, leftAxis);
// }
// }
//
//
//
//
// /**
// * 构建多个图形对象
// * @param dataSourceSheet
// * @param tragetSheet
// * @param graphList
// */
// private static void buildExcelChart(Sheet dataSourceSheet,Sheet tragetSheet,List<ExcelGraph> graphList){
// int len=graphList.size();
// if(len==1)
// {
// buildExcelChart(dataSourceSheet, tragetSheet, graphList.get(0));
// }
// else
// {
// int drawStart=0;
// int drawEnd=20;
// Drawing drawing = PoiExcelGraphDataUtil.getDrawingPatriarch(tragetSheet);
// for(int i=0;i<len;i++){
// ExcelGraph graph=graphList.get(i);
// ClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 0, drawStart, 15, drawEnd);
// buildExcelChart(drawing, anchor, dataSourceSheet, graph);
// drawStart=drawStart+drawEnd;
// drawEnd=drawEnd+drawEnd;
// }
// }
// }
//
//
//
//
// /**
// * 构建图形对象
// * @param dataSourceSheet
// * @param tragetSheet
// * @param graph
// */
// private static void buildExcelChart(Sheet dataSourceSheet,Sheet tragetSheet,ExcelGraph graph){
// Drawing drawing = PoiExcelGraphDataUtil.getDrawingPatriarch(tragetSheet);
// ClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 0, 0, 15, 20);
// buildExcelChart(drawing, anchor, dataSourceSheet, graph);
// }
//
//
//
//
// /**
// * 构建Title
// * @param sheet
// * @param graph
// */
// private static void buildTitle(Sheet sheet,ExcelGraph graph){
// int cellTitleLen=graph.getTitleCell().size();
// int titleLen=graph.getTitle().size();
// if(titleLen>0){
//
// }else{
// for(int i=0;i<cellTitleLen;i++){
// ExcelTitleCell titleCell=graph.getTitleCell().get(i);
// if(titleCell!=null){
// graph.getTitle().add(PoiCellUtil.getCellValue(sheet,titleCell.getRow(),titleCell.getCol()));
// }
// }
// }
// }
//
// /**
// * 构建Title
// * @param sheet
// * @param graphList
// */
// private static void buildTitle(Sheet sheet,List<ExcelGraph> graphList){
// if(graphList!=null&&graphList.size()>0){
// for(ExcelGraph graph:graphList){
// if(graph!=null)
// {
// buildTitle(sheet, graph);
// }
// }
// }
// }
//
// /**
// *
// * @param data
// * @param categoryChart
// * @param chartValueList
// * @param title
// */
// private static void buildLineChartData(LineChartData data,ChartDataSource categoryChart,List<ChartDataSource<Number>> chartValueList,List<String> title){
// if(chartValueList.size()==title.size())
// {
// int len=title.size();
// for(int i=0;i<len;i++){
// //TODO 更新版本
// //data.addSerie(categoryChart, chartValueList.get(i)).setTitle(title.get(i));
// }
// }
// else
// {
// int i=0;
// for(ChartDataSource<Number> source:chartValueList){
// String temp_title=title.get(i);
// if(StringUtils.isNotBlank(temp_title)){
// //data.addSerie(categoryChart, source).setTitle(_title);
// }else{
// //data.addSerie(categoryChart, source);
// }
// }
// }
// }
//
// /**
// *
// * @param data
// * @param categoryChart
// * @param chartValueList
// * @param title
// */
// private static void buildScatterChartData(ScatterChartData data,ChartDataSource categoryChart,List<ChartDataSource<Number>> chartValueList,List<String> title){
// if(chartValueList.size()==title.size())
// {
// int len=title.size();
// for(int i=0;i<len;i++){
// data.addSerie(categoryChart, chartValueList.get(i)).setTitle(title.get(i));
// }
// }
// else
// {
// int i=0;
// for(ChartDataSource<Number> source:chartValueList){
// String temp_title=title.get(i);
// if(StringUtils.isNotBlank(temp_title)){
// data.addSerie(categoryChart, source).setTitle(temp_title);
// }else{
// data.addSerie(categoryChart, source);
// }
// }
// }
// }
//
//
//}

View File

@@ -0,0 +1,15 @@
/**
*
*/
package org.jeecgframework.poi.excel.graph.constant;
/**
* @Description 定义元素类型
* @author liusq
* @date 2022年1月4号
*/
public interface ExcelGraphElementType
{
public static final Integer STRING_TYPE =1;
public static final Integer NUMERIC_TYPE =2;
}

View File

@@ -0,0 +1,16 @@
/**
*
*/
package org.jeecgframework.poi.excel.graph.constant;
/**
* @Description 定义图形类型
* @author liusq
* @date 2022年1月4号
*/
public interface ExcelGraphType
{
public static final Integer LINE_CHART =1;
public static final Integer SCATTER_CHART =2;
}

View File

@@ -0,0 +1,20 @@
/**
*
*/
package org.jeecgframework.poi.excel.graph.entity;
import java.util.List;
/**
* @Description Excel 图形构造服务
* @author liusq
* @date 2022年1月4号
*/
public interface ExcelGraph
{
public ExcelGraphElement getCategory();
public List<ExcelGraphElement> getValueList();
public Integer getGraphType();
public List<ExcelTitleCell> getTitleCell();
public List<String> getTitle();
}

View File

@@ -0,0 +1,74 @@
/**
*
*/
package org.jeecgframework.poi.excel.graph.entity;
import org.jeecgframework.poi.excel.graph.constant.ExcelGraphType;
import java.util.ArrayList;
import java.util.List;
/**
* @Description Excel 图形构造服务
* @author liusq
* @date 2022年1月4号
*/
public class ExcelGraphDefined implements ExcelGraph
{
private ExcelGraphElement category;
public List<ExcelGraphElement> valueList= new ArrayList<>();
public List<ExcelTitleCell> titleCell= new ArrayList<>();
private Integer graphType= ExcelGraphType.LINE_CHART;
public List<String> title= new ArrayList<>();
@Override
public ExcelGraphElement getCategory()
{
return category;
}
public void setCategory(ExcelGraphElement category)
{
this.category = category;
}
@Override
public List<ExcelGraphElement> getValueList()
{
return valueList;
}
public void setValueList(List<ExcelGraphElement> valueList)
{
this.valueList = valueList;
}
@Override
public Integer getGraphType()
{
return graphType;
}
public void setGraphType(Integer graphType)
{
this.graphType = graphType;
}
@Override
public List<ExcelTitleCell> getTitleCell()
{
return titleCell;
}
public void setTitleCell(List<ExcelTitleCell> titleCell)
{
this.titleCell = titleCell;
}
@Override
public List<String> getTitle()
{
return title;
}
public void setTitle(List<String> title)
{
this.title = title;
}
}

View File

@@ -0,0 +1,63 @@
/**
*
*/
package org.jeecgframework.poi.excel.graph.entity;
import org.jeecgframework.poi.excel.graph.constant.ExcelGraphElementType;
/**
* @Description Excel 图形构造服务
* @author liusq
* @date 2022年1月4号
*/
public class ExcelGraphElement
{
private Integer startRowNum;
private Integer endRowNum;
private Integer startColNum;
private Integer endColNum;
private Integer elementType= ExcelGraphElementType.STRING_TYPE;
public Integer getStartRowNum()
{
return startRowNum;
}
public void setStartRowNum(Integer startRowNum)
{
this.startRowNum = startRowNum;
}
public Integer getEndRowNum()
{
return endRowNum;
}
public void setEndRowNum(Integer endRowNum)
{
this.endRowNum = endRowNum;
}
public Integer getStartColNum()
{
return startColNum;
}
public void setStartColNum(Integer startColNum)
{
this.startColNum = startColNum;
}
public Integer getEndColNum()
{
return endColNum;
}
public void setEndColNum(Integer endColNum)
{
this.endColNum = endColNum;
}
public Integer getElementType()
{
return elementType;
}
public void setElementType(Integer elementType)
{
this.elementType = elementType;
}
}

View File

@@ -0,0 +1,43 @@
/**
*
*/
package org.jeecgframework.poi.excel.graph.entity;
/**
* @Description Excel 图形构造服务
* @author liusq
* @date 2022年1月4号
*/
public class ExcelTitleCell
{
private Integer row;
private Integer col;
public ExcelTitleCell(){
}
public ExcelTitleCell(Integer row,Integer col){
this.row=row;
this.col=col;
}
public Integer getRow()
{
return row;
}
public void setRow(Integer row)
{
this.row = row;
}
public Integer getCol()
{
return col;
}
public void setCol(Integer col)
{
this.col = col;
}
}

View File

@@ -0,0 +1,9 @@
/**
*
*/
/**
* @Description Excel 图形构造服务
* @author liusq
* @date 2022年1月4号
*/
package org.jeecgframework.poi.excel.graph;

View File

@@ -0,0 +1,191 @@
package org.jeecgframework.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 org.jeecgframework.poi.excel.html.helper.CellValueHelper;
import org.jeecgframework.poi.excel.html.helper.MergedRegionHelper;
import org.jeecgframework.poi.excel.html.helper.StylerHelper;
/**
* Excel转换成Html 服务
*
* @author JEECG
* @date 2015年5月10日 上午11:41:15
*/
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")
/**本来是用来生成 AB 那个列名称的**/
private void printColumnHeads(Sheet sheet) {
out.format("<thead>%n");
out.format(" <tr class=%s>%n", COL_HEAD_CLASS);
out.format(" <th class=%s>&#x25CA;</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 = "&nbsp;";
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);
}
}

View File

@@ -0,0 +1,135 @@
package org.jeecgframework.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.CellType;
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;
/**
* Cell值帮助类
*
* @author JEECG
* @date 2015年5月9日 下午10:31:32
*/
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 (int i = 0, le = wb.getNumberOfFonts(); i < le; i++) {
Font font = wb.getFontAt(i);
fontCache.put(font.getBold() + "_" + font.getItalic() + "_" + font.getFontName() + "_" + font.getFontHeightInPoints() + "_" + font.getColor(), font.getIndex() + "");
}
}
public String getHtmlValue(Cell cell) {
if (CellType.BOOLEAN == cell.getCellType() || CellType.NUMERIC == cell.getCellType()) {
cell.setCellType( CellType.STRING);
return cell.getStringCellValue();
} else if ( CellType.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.getBold() + "_" + font.getItalic() + "_" + font.getFontName() + "_" + font.getFontHeightInPoints() + "_" + font.getColor());
}
}

View File

@@ -0,0 +1,139 @@
package org.jeecgframework.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;
import org.jeecgframework.poi.util.PoiCellUtil;
import org.jeecgframework.poi.util.PoiMergeCellUtil;
/**
* 合并单元格帮助类
*
* @author JEECG
* @date 2015年5月9日 下午2:13:35
*/
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);
}
/**
* 插入之后还原之前的合并单元格
*
* @param rowIndex
* @param size
*/
public void shiftRows(Sheet sheet, int rowIndex, int size, int shiftRows) {
Set<String> keys = new HashSet<String>();
keys.addAll(mergedCache.keySet());
for (String key : keys) {
String[] temp = key.split("_");
//update-begin---author:chenrui ---date:20240102 for[issue/5167]遍历单元格次行原本的合并缓存未正确删除导致最终输出合并样式有问题------------
if (Integer.parseInt(temp[0]) > rowIndex) {
//update-end---author:chenrui ---date:20240102 for[issue/5167]遍历单元格次行原本的合并缓存未正确删除导致最终输出合并样式有问题------------
Integer[] data = mergedCache.get(key);
String newKey = (Integer.parseInt(temp[0]) + size) + "_" + temp[1];
if (!mergedCache.containsKey(newKey)) {
mergedCache.put(newKey, mergedCache.get(key));
try {
// 还原合并单元格
if (!PoiCellUtil.isMergedRegion(sheet, Integer.parseInt(temp[0]) + size - 1, Integer.parseInt(temp[1]))) {
PoiMergeCellUtil.addMergedRegion(sheet,
Integer.parseInt(temp[0]) + size - 1, Integer.parseInt(temp[0]) + data[0] + size - 2,
Integer.parseInt(temp[1]), Integer.parseInt(temp[1]) + data[1] - 1
);
}
} catch (Exception e) {
}
}
}
}
//删除掉原始的缓存KEY
for (String key : keys) {
String[] temp = key.split("_");
//update-begin---author:chenrui ---date:20240102 for[issue/5167]遍历单元格次行原本的合并缓存未正确删除导致最终输出合并样式有问题------------
if (Integer.parseInt(temp[0]) >= rowIndex && Integer.parseInt(temp[0]) <= rowIndex + size ) {
//update-end---author:chenrui ---date:20240102 for[issue/5167]遍历单元格次行原本的合并缓存未正确删除导致最终输出合并样式有问题------------
mergedCache.remove(key);
}
}
}
}

View File

@@ -0,0 +1,259 @@
package org.jeecgframework.poi.excel.html.helper;
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.*;
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 org.jeecgframework.poi.util.PoiPublicUtil;
/**
* 样式帮助类
*
* @author JEECG
* @date 2015年5月9日 下午4:04:24
*/
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(HorizontalAlignment.LEFT.getCode(), "left",HorizontalAlignment.CENTER.getCode(), "center",HorizontalAlignment.RIGHT.getCode(), "right", HorizontalAlignment.FILL.getCode(), "left",HorizontalAlignment.JUSTIFY.getCode(), "left",HorizontalAlignment.CENTER_SELECTION.getCode(), "center");
private static final Map<Short, String> VERTICAL_ALIGN = PoiPublicUtil.mapFor(VerticalAlignment.BOTTOM.getCode(), "bottom", VerticalAlignment.CENTER.getCode(), "middle",VerticalAlignment.TOP.getCode(), "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) {
//update-begin---author:liusq Date:20220228 for[I4I3ZY]issue AutoPOi Workbook对象转HTML字符串 数组下标越界异常----
for (int 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");
}
//update-end---author:liusq Date:20220228 for[I4I3ZY]issue AutoPOi Workbook对象转HTML字符串 数组下标越界异常整----
}
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().getCode() != 2) {
styleOut("text-align", style.getAlignment().getCode(), ALIGN);
styleOut("vertical-align", style.getAlignment().getCode(), VERTICAL_ALIGN);
}
helper.colorStyles(style, out);
}
private void fontStyle(Font font) {
if (font.getBold())
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;
//-------author:liusq------date:20210129-----for:-------poi3升级到4兼容改造工作【重要敏感修改点】--------
private HSSFColor HSSF_AUTO = new HSSFColor(0x40, -1, java.awt.Color.black);
//-------author:liusq------date:20210129-----for:-------poi3升级到4兼容改造工作【重要敏感修改点】--------
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]);
}
}
}

View File

@@ -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;
}

View File

@@ -0,0 +1,387 @@
/**
* Copyright 2013-2015 JEECG (jeecgos@163.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jeecgframework.poi.excel.imports;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.jeecgframework.poi.excel.entity.params.ExcelImportEntity;
import org.jeecgframework.poi.excel.entity.sax.SaxReadCellEntity;
import org.jeecgframework.poi.exception.excel.ExcelImportException;
import org.jeecgframework.poi.exception.excel.enums.ExcelImportEnum;
import org.jeecgframework.poi.handler.inter.IExcelDataHandler;
import org.jeecgframework.poi.util.ExcelUtil;
import org.jeecgframework.poi.util.PoiPublicUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.math.RoundingMode;
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;
/**
* Cell 取值服务 判断类型处理数据 1.判断Excel中的类型 2.根据replace替换值 3.handler处理数据 4.判断返回类型转化数据返回
*
* @author JEECG
* @date 2014年6月26日 下午10:42:28
*/
public class CellValueServer {
private static final Logger LOGGER = LoggerFactory.getLogger(CellValueServer.class);
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 ( CellType.NUMERIC == cell.getCellType()) {
// 日期格式
result = cell.getDateCellValue();
} else {
cell.setCellType( CellType.STRING);
result = getDateData(entity, cell.getStringCellValue());
}
if (("class java.sql.Time").equals(xclass)) {
result = new Time(((Date) result).getTime());
}
} else if ( CellType.NUMERIC == cell.getCellType()) {
result = cell.getNumericCellValue();
} else if ( CellType.BOOLEAN == cell.getCellType()) {
result = cell.getBooleanCellValue();
} else if ( CellType.FORMULA == cell.getCellType() && PoiPublicUtil.isNumber(xclass)) {
//如果单元格是表达式 且 字段是数字类型
double cellValue = cell.getNumericCellValue();
//---author:liusq---date:20221102-----for: [issues/3369]Excel导入 带公式的时候精度丢失---
//setScale方法的第一个参数设置小数点保留位数第二个参数设置进位方法、此处是四舍五入
BigDecimal bigDecimal= new BigDecimal(cellValue).setScale(4, RoundingMode.HALF_UP);
//stripTrailingZeros方法去除末尾的0toPlainString避免输出科学计数法的字符串
result = bigDecimal.stripTrailingZeros().toPlainString();
//---author:liusq---date:20221102-----for:[issues/3369] Excel导入 带公式的时候精度丢失---
} else {
//设置单元格类型
cell.setCellType(CellType.STRING);
result = cell.getStringCellValue();
}
return result;
}
/**
* 获取日期类型数据
*
* @Author JEECG
* @date 2013年11月26日
* @param entity
* @param value
* @return
*/
private Date getDateData(ExcelImportEntity entity, String value) {
if (StringUtils.isNotEmpty(entity.getFormat()) && StringUtils.isNotEmpty(value)) {
SimpleDateFormat format = new SimpleDateFormat(entity.getFormat());
try {
return format.parse(value);
} catch (ParseException e) {
LOGGER.error("时间格式化失败,格式化:{},值:{}", entity.getFormat(), value);
throw new ExcelImportException(ExcelImportEnum.GET_VALUE_ERROR);
}
}
return null;
}
/**
* 获取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);
//update-begin-author:taoYan date:20180807 for:多值替换
result = replaceValue(entity.getReplace(), result,entity.isMultiReplace());
//update-end-author:taoYan date:20180807 for:多值替换
}
result = hanlderValue(dataHanlder, object, result, titleString);
return getValueByType(xclass, result, entity);
}
/**
* 获取cell值
*
* @param dataHanlder
* @param object
* @param cellEntity
* @param excelParams
* @param titleString
* @return
*/
public Object getValue(IExcelDataHandler dataHanlder, Object object, SaxReadCellEntity cellEntity, Map<String, ExcelImportEntity> excelParams, String titleString) {
ExcelImportEntity entity = excelParams.get(titleString);
Method setMethod = entity.getMethods() != null && entity.getMethods().size() > 0 ? entity.getMethods().get(entity.getMethods().size() - 1) : entity.getMethod();
Type[] ts = setMethod.getGenericParameterTypes();
String xclass = ts[0].toString();
Object result = cellEntity.getValue();
result = hanlderSuffix(entity.getSuffix(), result);
//update-begin-auhtor:taoyan date:20180807 for:多值替换
result = replaceValue(entity.getReplace(), result,entity.isMultiReplace());
//update-end-auhtor:taoyan date:20180807 for:多值替换
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)) {
//update-begin-author:taoYan date:20200319 for:Excel注解的numFormat方法似乎未实现 #970
Boolean temp = Boolean.valueOf(String.valueOf(result));
//if(StringUtils.isNotEmpty(entity.getNumFormat())){
// return Boolean.valueOf(new DecimalFormat(entity.getNumFormat()).format(temp));
//}else{
return temp;
//}
//update-end-author:taoYan date:20200319 for:Excel注解的numFormat方法似乎未实现 #970
}
if ("class java.lang.Double".equals(xclass) || "double".equals(xclass)) {
//update-begin-author:taoYan date:20200319 for:Excel注解的numFormat方法似乎未实现 #970
Double temp = Double.valueOf(String.valueOf(result));
//if(StringUtils.isNotEmpty(entity.getNumFormat())){
// return Double.valueOf(new DecimalFormat(entity.getNumFormat()).format(temp));
//}else{
return temp;
//}
//update-end-author:taoYan date:20200319 for:Excel注解的numFormat方法似乎未实现 #970
}
if ("class java.lang.Long".equals(xclass) || "long".equals(xclass)) {
//update-begin-author:taoYan date:20200319 for:Excel注解的numFormat方法似乎未实现 #970
Long temp = Long.valueOf(ExcelUtil.remove0Suffix(String.valueOf(result)));
//if(StringUtils.isNotEmpty(entity.getNumFormat())){
// return Long.valueOf(new DecimalFormat(entity.getNumFormat()).format(temp));
//}else{
return temp;
//}
//update-end-author:taoYan date:20200319 for:Excel注解的numFormat方法似乎未实现 #970
}
if ("class java.lang.Float".equals(xclass) || "float".equals(xclass)) {
//update-begin-author:taoYan date:20200319 for:Excel注解的numFormat方法似乎未实现 #970
Float temp = Float.valueOf(String.valueOf(result));
//if(StringUtils.isNotEmpty(entity.getNumFormat())){
// return Float.valueOf(new DecimalFormat(entity.getNumFormat()).format(temp));
//}else{
return temp;
//}
//update-end-author:taoYan date:20200319 for:Excel注解的numFormat方法似乎未实现 #970
}
if ("class java.lang.Integer".equals(xclass) || "int".equals(xclass)) {
//update-begin-author:taoYan date:20200319 for:Excel注解的numFormat方法似乎未实现 #970
Integer temp = Integer.valueOf(ExcelUtil.remove0Suffix(String.valueOf(result)));
//if(StringUtils.isNotEmpty(entity.getNumFormat())){
// return Integer.valueOf(new DecimalFormat(entity.getNumFormat()).format(temp));
//}else{
return temp;
//}
//update-end-author:taoYan date:20200319 for:Excel注解的numFormat方法似乎未实现 #970
}
if ("class java.math.BigDecimal".equals(xclass)) {
//update-begin-author:taoYan date:20200319 for:Excel注解的numFormat方法似乎未实现 #970
BigDecimal temp = new BigDecimal(String.valueOf(result));
//if(StringUtils.isNotEmpty(entity.getNumFormat())){
// return new BigDecimal(new DecimalFormat(entity.getNumFormat()).format(temp));
//}else{
return temp;
//}
//update-end-author:taoYan date:20200319 for:Excel注解的numFormat方法似乎未实现 #970
}
if ("class java.lang.String".equals(xclass)) {
// 针对String 类型,但是Excel获取的数据却不是String,比如Double类型,防止科学计数法
if (result instanceof String) {
//---update-begin-----autor:scott------date:20191016-------for:excel导入数字类型去掉后缀.0------
return ExcelUtil.remove0Suffix(result);
//---update-end-----autor:scott------date:20191016-------for:excel导入数字类型去掉后缀.0------
}
// double类型防止科学计数法
if (result instanceof Double) {
return PoiPublicUtil.doubleToString((Double) result);
}
//---update-begin-----autor:scott------date:20191016-------for:excel导入数字类型去掉后缀.0------
return ExcelUtil.remove0Suffix(String.valueOf(result));
//---update-end-----autor:scott------date:20191016-------for:excel导入数字类型去掉后缀.0------
}
return result;
} catch (Exception e) {
LOGGER.error(e.getMessage(), e);
throw new ExcelImportException(ExcelImportEnum.GET_VALUE_ERROR);
}
}
/**
* 调用处理接口处理值
*
* @param dataHanlder
* @param object
* @param result
* @param titleString
* @return
*/
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;
}
//update-begin-author:taoyan date:20180807 for:导入多值替换--
/**
* 导入支持多值替换
* @param replace 数据库中字典查询出来的数组
* @param result excel单元格获取的值
* @param multiReplace 是否支持多值替换
* @author taoYan
* @since 2018年8月7日
*/
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);
}
//update-begin-author:liusq date:20210204 for:字典替换失败提示日志
if(replace.length>0 && backValue.equals(temp)){
LOGGER.warn("====================字典替换失败,字典值:{},要转换的导入值:{}====================", replace, temp);
}
//update-end-author:liusq date:20210204 for:字典替换失败提示日志
return backValue;
}
/**
* 单值替换 ,若没找到则原值返回
*/
private String replaceSingleValue(String[] replace, String temp){
String[] tempArr;
for (int i = 0; i < replace.length; i++) {
//update-begin---author:scott Date:20211220 for[issues/I4MBB3]@Excel dicText字段的值有下划线时导入功能不能正确解析---
//tempArr = replace[i].split("_");
tempArr = getValueArr(replace[i]);
if (temp.equals(tempArr[0]) || temp.replace("_","---").equals(tempArr[0])) {
//update-begin---author:wangshuai ---date:20220422 for导入字典替换需要将---替换成_不然数据库会存--- ------------
if(tempArr[1].contains("---")){
return tempArr[1].replace("---","_");
}
//update-end---author:wangshuai ---date:20220422 for导入字典替换需要将---替换成_不然数据库会存--- --------------
return tempArr[1];
}
//update-end---author:scott Date:20211220 for[issues/I4MBB3]@Excel dicText字段的值有下划线时导入功能不能正确解析---
}
return temp;
}
//update-end-author:taoyan date:20180807 for:导入多值替换--
/**
* 字典文本中含多个下划线横岗,取最后一个(解决空值情况)
*
* @param val
* @return
*/
public String[] getValueArr(String val) {
int i = val.lastIndexOf("_");//最后一个分隔符的位置
String[] c = new String[2];
c[0] = val.substring(0, i); //label
c[1] = val.substring(i + 1); //key
return c;
}
}

View File

@@ -0,0 +1,620 @@
/**
* Copyright 2013-2015 JEECG (jeecgos@163.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jeecgframework.poi.excel.imports;
import org.apache.commons.lang3.StringUtils;
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.FileMagic;
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 org.jeecgframework.core.util.ApplicationContextUtil;
import org.jeecgframework.poi.excel.annotation.ExcelTarget;
import org.jeecgframework.poi.excel.entity.ImportParams;
import org.jeecgframework.poi.excel.entity.params.ExcelCollectionParams;
import org.jeecgframework.poi.excel.entity.params.ExcelImportEntity;
import org.jeecgframework.poi.excel.entity.result.ExcelImportResult;
import org.jeecgframework.poi.excel.entity.result.ExcelVerifyHanlderResult;
import org.jeecgframework.poi.excel.imports.base.ImportBaseService;
import org.jeecgframework.poi.excel.imports.base.ImportFileServiceI;
import org.jeecgframework.poi.excel.imports.verifys.VerifyHandlerServer;
import org.jeecgframework.poi.exception.excel.ExcelImportException;
import org.jeecgframework.poi.exception.excel.enums.ExcelImportEnum;
import org.jeecgframework.poi.util.ExcelUtil;
import org.jeecgframework.poi.util.PoiPublicUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Excel 导入服务
*
* @author JEECG
* @date 2014年6月26日 下午9:20:51
*/
@SuppressWarnings({ "rawtypes", "unchecked", "hiding" })
public class ExcelImportServer extends ImportBaseService {
private final static Logger LOGGER = LoggerFactory.getLogger(ExcelImportServer.class);
private CellValueServer cellValueServer;
private VerifyHandlerServer verifyHandlerServer;
private boolean verfiyFail = false;
//仅允许字母数字字符的正则表达式
private static final Pattern lettersAndNumbersPattern = Pattern.compile("^[a-zA-Z0-9]+$") ;
/**
* 异常数据styler
*/
private CellStyle errorCellStyle;
public ExcelImportServer() {
this.cellValueServer = new CellValueServer();
this.verifyHandlerServer = new VerifyHandlerServer();
}
/***
* 向List里面继续添加元素
*
* @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的值,针对不同类型获取不同的值
*
* @Author JEECG
* @date 2013-11-21
* @param cell
* @return
*/
private String getKeyValue(Cell cell) {
if(cell==null){
return null;
}
Object obj = null;
switch (cell.getCellType()) {
case STRING:
obj = cell.getStringCellValue();
break;
case BOOLEAN:
obj = cell.getBooleanCellValue();
break;
case NUMERIC:
obj = cell.getNumericCellValue();
break;
case 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();
}
//update-begin--Author:xuelin Date:20171205 forTASK #2098 【excel问题】 Online 一对多导入失败--------------------
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);
}
ignoreHeaderHandler(excelParams, params);
Iterator<Row> rows = sheet.rowIterator();
Map<Integer, String> titlemap = getTitleMap(sheet, rows, params, excelCollection);
//update-begin-author:liusq date:20220310 for:[issues/I4PU45]@excel里面新增属性fixedIndex
Set<String> keys = excelParams.keySet();
for (String key : keys) {
if (key.startsWith("FIXED_")) {
String[] arr = key.split("_");
titlemap.put(Integer.parseInt(arr[1]), key);
}
}
//update-end-author:liusq date:20220310 for:[issues/I4PU45]@excel里面新增属性fixedIndex
Set<Integer> columnIndexSet = titlemap.keySet();
Integer maxColumnIndex = Collections.max(columnIndexSet);
Integer minColumnIndex = Collections.min(columnIndexSet);
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();
//update-begin--Author:xuelin Date:20171017 forTASK #2373 【bug】表改造问题导致 3.7.1批量导入用户bug-导入不成功--------------------
// 判断是集合元素还是不是集合元素,如果是就继续加入这个集合,不是就创建新的对象
//update-begin--Author:xuelin Date:20171206 forTASK #2451 【excel导出bug】online 一对多导入成功, 但是现在代码生成后的一对多online导入有问题了
Cell keyIndexCell = row.getCell(params.getKeyIndex());
if (excelCollection.size()>0 && StringUtils.isEmpty(getKeyValue(keyIndexCell)) && object != null && !Map.class.equals(pojoClass)) {
//update-end--Author:xuelin Date:20171206 forTASK #2451 【excel导出bug】online 一对多导入成功, 但是现在代码生成后的一对多online导入有问题了
for (ExcelCollectionParams param : excelCollection) {
addListContinue(object, param, row, titlemap, targetId, pictures, params);
}
} else {
object = PoiPublicUtil.createObject(pojoClass, targetId);
try {
//update-begin-author:taoyan date:20200303 for:导入图片
int firstCellNum = row.getFirstCellNum();
if(firstCellNum>minColumnIndex){
firstCellNum = minColumnIndex;
}
int lastCellNum = row.getLastCellNum();
if(lastCellNum<maxColumnIndex+1){
lastCellNum = maxColumnIndex+1;
}
for (int i = firstCellNum, le = lastCellNum; 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 {
if(params.getImageList()!=null && params.getImageList().contains(titleString)){
if (pictures != null) {
picId = row.getRowNum() + "_" + i;
PictureData image = pictures.get(picId);
if(image!=null){
byte[] data = image.getData();
params.getDataHanlder().setMapValue((Map) object, titleString, data);
}
}
}else{
saveFieldValue(params, object, cell, excelParams, titleString, row);
}
//update-end-author:taoyan date:20200303 for:导入图片
}
}
}
for (ExcelCollectionParams param : excelCollection) {
addListContinue(object, param, row, titlemap, targetId, pictures, params);
}
//update-begin-author:taoyan date:20210526 for:autopoi导入excel 如果单元格被设置边框,即使没有内容也会被当做是一条数据导入 #2484
if(isNotNullObject(pojoClass, object)){
collection.add(object);
}
//update-end-author:taoyan date:20210526 for:autopoi导入excel 如果单元格被设置边框,即使没有内容也会被当做是一条数据导入 #2484
} catch (ExcelImportException e) {
if (!e.getType().equals(ExcelImportEnum.VERIFY_ERROR)) {
throw new ExcelImportException(e.getType(), e);
}
}
}
//update-end--Author:xuelin Date:20171017 forTASK #2373 【bug】表改造问题导致 3.7.1批量导入用户bug-导入不成功--------------------
}
return collection;
}
/**
* 判断当前对象不是空
* @param pojoClass
* @param object
* @return
*/
private boolean isNotNullObject(Class pojoClass, Object object){
try {
Method method = pojoClass.getMethod("isNullObject");
if(method!=null){
Object flag = method.invoke(object);
if(flag!=null && true == Boolean.parseBoolean(flag.toString())){
return false;
}
}
} catch (NoSuchMethodException e) {
LOGGER.debug("未定义方法 isNullObject");
} catch (IllegalAccessException e) {
LOGGER.warn("没有权限访问该方法 isNullObject");
} catch (InvocationTargetException e) {
LOGGER.warn("方法调用失败 isNullObject");
}
return true;
}
/**
* 获取忽略的表头信息
* @param excelParams
* @param params
*/
private void ignoreHeaderHandler(Map<String, ExcelImportEntity> excelParams,ImportParams params){
List<String> ignoreList = new ArrayList<>();
for(String key:excelParams.keySet()){
String temp = excelParams.get(key).getGroupName();
if(temp!=null && temp.length()>0){
ignoreList.add(temp);
}
}
params.setIgnoreHeaderList(ignoreList);
}
/**
* 获取表格字段列名对应信息
*
* @param rows
* @param params
* @param excelCollection
* @return
*/
private Map<Integer, String> getTitleMap(Sheet sheet, Iterator<Row> rows, ImportParams params, List<ExcelCollectionParams> excelCollection) throws Exception {
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();
//update_begin-author:taoyan date:2020622 for当文件行数小于代码里设置的TitleRows时headRow一直为空就会出现死循环
int allRowNum = sheet.getPhysicalNumberOfRows();
//找到首行表头每个sheet都必须至少有一行表头
while(headRow == null && headBegin < allRowNum){
headRow = sheet.getRow(headBegin++);
}
if(headRow==null){
throw new Exception("不识别该文件");
}
//update-end-author:taoyan date:2020622 for当文件行数小于代码里设置的TitleRows时headRow一直为空就会出现死循环
//设置表头行数
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);
if(params.isIgnoreHeader(collectionName)){
titlemap.put(cell.getColumnIndex(), value);
}else{
titlemap.put(cell.getColumnIndex(), collectionName + "_" + value);
}
}else{
//update-begin-author:taoyan date:20220112 for: JT640 【online】导入 无论一对一还是一对多 如果子表只有一个字段 则子表无数据
// 上一行不是合并的情况下另有一种特殊的场景: 如果当前单元格和上面的单元格同一列 即子表字段只有一个 所以标题没有出现跨列
String prefixTitle = titlemap.get(cell.getColumnIndex());
if(prefixTitle!=null && !"".equals(prefixTitle)){
titlemap.put(cell.getColumnIndex(), prefixTitle + "_" +value);
}else{
titlemap.put(cell.getColumnIndex(), value);
}
//update-end-author:taoyan date:20220112 for: JT640 【online】导入 无论一对一还是一对多 如果子表只有一个字段 则子表无数据
}
/*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;
}
//update-end--Author:xuelin Date:20171205 forTASK #2098 【excel问题】 Online 一对多导入失败--------------------
/**
* 获取这个名称对应的集合信息
*
* @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 (LOGGER.isDebugEnabled()) {
LOGGER.debug("Excel import start ,class is {}", pojoClass);
}
List<T> result = new ArrayList<T>();
Workbook book = null;
boolean isXSSFWorkbook = false;
if (!(inputstream.markSupported())) {
inputstream = new PushbackInputStream(inputstream, 8);
}
//begin-------author:liusq------date:20210129-----for:-------poi3升级到4兼容改造工作【重要敏感修改点】--------
//------poi4.x begin----
// FileMagic fm = FileMagic.valueOf(FileMagic.prepareToCheckMagic(inputstream));
// if(FileMagic.OLE2 == fm){
// isXSSFWorkbook=false;
// }
book = WorkbookFactory.create(inputstream);
if(book instanceof XSSFWorkbook){
isXSSFWorkbook=true;
}
LOGGER.info(" >>> poi3升级到4.0兼容改造工作, isXSSFWorkbook = " +isXSSFWorkbook);
//end-------author:liusq------date:20210129-----for:-------poi3升级到4兼容改造工作【重要敏感修改点】--------
//begin-------author:liusq------date:20210313-----for:-------多sheet导入改造点--------
//获取导入文本的sheet数
//update-begin-author:taoyan date:20211210 for:https://gitee.com/jeecg/jeecg-boot/issues/I45C32 导入空白sheet报错
if(params.getSheetNum()==0){
int sheetNum = book.getNumberOfSheets();
if(sheetNum>0){
params.setSheetNum(sheetNum);
}
}
//update-end-author:taoyan date:20211210 for:https://gitee.com/jeecg/jeecg-boot/issues/I45C32 导入空白sheet报错
//end-------author:liusq------date:20210313-----for:-------多sheet导入改造点--------
createErrorCellStyle(book);
Map<String, PictureData> pictures;
// 获取指定的sheet名称
String sheetName = params.getSheetName();
//update-begin-author:liusq date:20220609 for:issues/I57UPC excel导入 ImportParams 中没有startSheetIndex参数
for (int i = params.getStartSheetIndex(); i < params.getStartSheetIndex()
+ params.getSheetNum(); i++) {
//update-end-author:liusq date:20220609 for:issues/I57UPC excel导入 ImportParams 中没有startSheetIndex参数
//update-begin-author:taoyan date:2023-3-4 for: 导入数据支持指定sheet名称
if(sheetName!=null && !"".equals(sheetName)){
Sheet tempSheet = book.getSheetAt(i);
if(!sheetName.equals(tempSheet.getSheetName())){
continue;
}
}
//update-end-author:taoyan date:2023-3-4 for: 导入数据支持指定sheet名称
if (LOGGER.isDebugEnabled()) {
LOGGER.debug(" start to read excel by is ,startTime is {}", System.currentTimeMillis());
}
if (isXSSFWorkbook) {
pictures = PoiPublicUtil.getSheetPictrues07((XSSFSheet) book.getSheetAt(i), (XSSFWorkbook) book);
} else {
pictures = PoiPublicUtil.getSheetPictrues03((HSSFSheet) book.getSheetAt(i), (HSSFWorkbook) book);
}
if (LOGGER.isDebugEnabled()) {
LOGGER.debug(" end to read excel by is ,endTime is {}", new Date().getTime());
}
result.addAll(importExcel(result, book.getSheetAt(i), pojoClass, params, pictures));
if (LOGGER.isDebugEnabled()) {
LOGGER.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 is
* @return
* @throws IOException
*/
public static byte[] getBytes(InputStream is) throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int len;
byte[] data = new byte[100000];
while ((len = is.read(data, 0, data.length)) != -1) {
buffer.write(data, 0, len);
}
buffer.flush();
return buffer.toByteArray();
}
/**
* 保存字段值(获取值,校验值,追加错误信息)
*
* @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 || pictures.get(picId)==null) {
return;
}
PictureData image = pictures.get(picId);
byte[] data = image.getData();
String fileName = "pic" + Math.round(Math.random() * 100000000000L);
fileName += "." + PoiPublicUtil.getFileExtendName(data);
//update-beign-author:taoyan date:20200302 for:【多任务】online 专项集中问题 LOWCOD-159
int saveType = excelParams.get(titleString).getSaveType();
if ( saveType == 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 if(saveType==2) {
setValues(excelParams.get(titleString), object, data);
} else {
ImportFileServiceI importFileService = null;
try {
importFileService = ApplicationContextUtil.getContext().getBean(ImportFileServiceI.class);
} catch (Exception e) {
System.err.println(e.getMessage());
}
if(importFileService!=null){
//update-beign-author:liusq date:20230411 for:【issue/4415】autopoi-web 导入图片字段时无法指定保存路径
String saveUrl = excelParams.get(titleString).getSaveUrl();
String dbPath;
if(StringUtils.isNotBlank(saveUrl)){
LOGGER.debug("图片保存路径saveUrl = "+saveUrl);
Matcher matcher = lettersAndNumbersPattern.matcher(saveUrl);
if(!matcher.matches()){
LOGGER.warn("图片保存路径格式错误,只能设置字母和数字的组合!");
dbPath = importFileService.doUpload(data);
}else{
dbPath = importFileService.doUpload(data,saveUrl);
}
}else{
dbPath = importFileService.doUpload(data);
}
//update-end-author:liusq date:20230411 for:【issue/4415】autopoi-web 导入图片字段时无法指定保存路径
setValues(excelParams.get(titleString), object, dbPath);
}
}
//update-end-author:taoyan date:20200302 for:【多任务】online 专项集中问题 LOWCOD-159
}
private void createErrorCellStyle(Workbook workbook) {
errorCellStyle = workbook.createCellStyle();
Font font = workbook.createFont();
font.setColor(Font.COLOR_RED);
errorCellStyle.setFont(font);
}
}

View File

@@ -0,0 +1,328 @@
/**
* Copyright 2013-2015 JEECG (jeecgos@163.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jeecgframework.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 org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.jeecgframework.core.util.ApplicationContextUtil;
import org.jeecgframework.dict.service.AutoPoiDictServiceI;
import org.jeecgframework.poi.excel.annotation.Excel;
import org.jeecgframework.poi.excel.annotation.ExcelCollection;
import org.jeecgframework.poi.excel.annotation.ExcelEntity;
import org.jeecgframework.poi.excel.annotation.ExcelVerify;
import org.jeecgframework.poi.excel.entity.ImportParams;
import org.jeecgframework.poi.excel.entity.params.ExcelCollectionParams;
import org.jeecgframework.poi.excel.entity.params.ExcelImportEntity;
import org.jeecgframework.poi.excel.entity.params.ExcelVerifyEntity;
import org.jeecgframework.poi.util.PoiPublicUtil;
/**
* 导入基础和,普通方法和Sax共用
*
* @author JEECG
* @date 2015年1月9日 下午10:25:53
*/
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.setNumFormat(excel.numFormat());
excelEntity.setGroupName(excel.groupName());
//update-begin-author:liusq date:20220310 for:[issues/I4PU45]@excel里面新增属性fixedIndex
excelEntity.setFixedIndex(excel.fixedIndex());
//update-end-author:liusq date:20220310 for:[issues/I4PU45]@excel里面新增属性fixedIndex
//update-begin-author:taoYan date:20180202 for:TASK #2067 【bug excel 问题】excel导入字典文本翻译问题
excelEntity.setMultiReplace(excel.multiReplace());
if(StringUtils.isNotEmpty(excel.dicCode())){
AutoPoiDictServiceI jeecgDictService = null;
try {
jeecgDictService = ApplicationContextUtil.getContext().getBean(AutoPoiDictServiceI.class);
} catch (Exception e) {
}
if(jeecgDictService!=null){
String[] dictReplace = jeecgDictService.queryDict(excel.dictTable(), excel.dicCode(), excel.dicText());
if(excelEntity.getReplace()!=null && dictReplace!=null && dictReplace.length!=0){
excelEntity.setReplace(dictReplace);
}
}
}
//update-end-author:taoYan date:20180202 for:TASK #2067 【bug excel 问题】excel导入字典文本翻译问题
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);
}
//update-begin-author:liusq date:20220310 for:[issues/I4PU45]@excel里面新增属性fixedIndex
if (excelEntity.getFixedIndex() != -1) {
temp.put("FIXED_" + excelEntity.getFixedIndex(), excelEntity);
} else {
temp.put(excelEntity.getName(), excelEntity);
}
//update-end-author:liusq date:20220310 for:[issues/I4PU45]@excel里面新增属性fixedIndex
}
/**
* 获取导入校验参数
*
* @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 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));
//update-begin-author:taoyan date:20210531 for:excel导入支持 注解@ExcelEntity显示合并表头
ExcelEntity excel = field.getAnnotation(ExcelEntity.class);
if(excel.show()==true){
Map<String, ExcelImportEntity> subExcelParams = new HashMap<>();
// 这里有个设计的坑导出的时候最后一个参数是null, 即getgetMethods获取的是空导入的时候需要设置层级getmethod
getAllExcelField(targetId, PoiPublicUtil.getClassFields(field.getType()), subExcelParams, excelCollection, field.getType(), newMethods);
for(String key: subExcelParams.keySet()){
excelParams.put(excel.name()+"_"+key, subExcelParams.get(key));
}
}else{
getAllExcelField(targetId, PoiPublicUtil.getClassFields(field.getType()), excelParams, excelCollection, field.getType(), newMethods);
}
//update-end-author:taoyan date:20210531 for:excel导入支持 注解@ExcelEntity显示合并表头
}
}
}
/**
* 追加集合名称到前面
*
* @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();
//update-begin-author:taoyan for:TASK #2798 【例子】导入扩展方法,支持自定义导入字段转换规则
excelEntity.setMethod(PoiPublicUtil.getMethod(fieldname, pojoClass, field.getType(),excel.importConvert()));
//update-end-author:taoyan for:TASK #2798 【例子】导入扩展方法,支持自定义导入字段转换规则
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;
}
if (StringUtils.isBlank(targetId)) {
return exportName;
}
String[] arr = exportName.split(",");
for (String str : arr) {
if (str.indexOf(targetId) != -1) {
//update-begin-author:liusq date20210127 for:targetId问题处理
//return str.split("_")[0];
return str.replace("_"+targetId,"");
//update-end-author:liusq date20210127 for:targetId问题处理
}
}
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);
}
}
}

View File

@@ -0,0 +1,20 @@
package org.jeecgframework.poi.excel.imports.base;
public interface ImportFileServiceI {
/**
* 上传文件 返回文件地址字符串
* @param data
* @return
*/
String doUpload(byte[] data);
/**
* 上传文件 返回文件地址字符串
* @param data
* @param saveUrl 保存路径
* @return
*/
String doUpload(byte[] data,String saveUrl);
}

View File

@@ -0,0 +1,6 @@
/**
* 导入类
* @author JEECG
* @date 2014年6月23日 下午11:05:59
*/
package org.jeecgframework.poi.excel.imports;

View File

@@ -0,0 +1,91 @@
/**
* Copyright 2013-2015 JEECG (jeecgos@163.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jeecgframework.poi.excel.imports.sax;
import java.io.InputStream;
import java.util.Iterator;
import java.util.List;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xssf.eventusermodel.XSSFReader;
import org.apache.poi.xssf.model.SharedStringsTable;
import org.jeecgframework.poi.excel.entity.ImportParams;
import org.jeecgframework.poi.excel.imports.sax.parse.ISaxRowRead;
import org.jeecgframework.poi.excel.imports.sax.parse.SaxRowRead;
import org.jeecgframework.poi.exception.excel.ExcelImportException;
import org.jeecgframework.poi.handler.inter.IExcelReadRowHanlder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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;
/**
* 基于SAX Excel大数据读取,读取Excel 07版本,不支持图片读取
*
* @author JEECG
* @date 2014年12月29日 下午9:41:38
* @version 1.0
*/
@SuppressWarnings("rawtypes")
public class SaxReadExcel {
private static final Logger LOGGER = LoggerFactory.getLogger(SaxReadExcel.class);
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) {
LOGGER.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 = (SharedStringsTable) 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) {
LOGGER.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;
}
}

View File

@@ -0,0 +1,136 @@
/**
* Copyright 2013-2015 JEECG (jeecgos@163.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jeecgframework.poi.excel.imports.sax;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.xssf.model.SharedStringsTable;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;
import org.jeecgframework.poi.excel.entity.enmus.CellValueType;
import org.jeecgframework.poi.excel.entity.sax.SaxReadCellEntity;
import org.jeecgframework.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 JEECG
* @date 2014年12月29日 下午9:50:09
*/
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 = sst.getItemAt(idx).getString();
} 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 = DateUtil.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);
}
}

View File

@@ -0,0 +1,39 @@
/**
* Copyright 2013-2015 JEECG (jeecgos@163.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jeecgframework.poi.excel.imports.sax.parse;
import java.util.List;
import org.jeecgframework.poi.excel.entity.sax.SaxReadCellEntity;
public interface ISaxRowRead {
/**
* 获取返回数据
*
* @param <T>
* @return
*/
public <T> List<T> getList();
/**
* 解析数据
*
* @param index
* @param datas
*/
public void parse(int index, List<SaxReadCellEntity> datas);
}

View File

@@ -0,0 +1,213 @@
/**
* Copyright 2013-2015 JEECG (jeecgos@163.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jeecgframework.poi.excel.imports.sax.parse;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import org.jeecgframework.poi.excel.annotation.ExcelTarget;
import org.jeecgframework.poi.excel.entity.ImportParams;
import org.jeecgframework.poi.excel.entity.params.ExcelCollectionParams;
import org.jeecgframework.poi.excel.entity.params.ExcelImportEntity;
import org.jeecgframework.poi.excel.entity.sax.SaxReadCellEntity;
import org.jeecgframework.poi.excel.imports.CellValueServer;
import org.jeecgframework.poi.excel.imports.base.ImportBaseService;
import org.jeecgframework.poi.exception.excel.ExcelImportException;
import org.jeecgframework.poi.handler.inter.IExcelReadRowHanlder;
import org.jeecgframework.poi.util.PoiPublicUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.collect.Lists;
/**
* 当行读取数据
*
* @author JEECG
* @param <T>
* @date 2015年1月1日 下午7:59:39
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
public class SaxRowRead extends ImportBaseService implements ISaxRowRead {
private static final Logger LOGGER = LoggerFactory.getLogger(SaxRowRead.class);
/** 需要返回的数据 **/
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) {
LOGGER.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) {
LOGGER.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()));
}
}
}
}

View File

@@ -0,0 +1,145 @@
/**
* Copyright 2013-2015 JEECG (jeecgos@163.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jeecgframework.poi.excel.imports.verifys;
import java.util.regex.Pattern;
import org.jeecgframework.poi.excel.entity.result.ExcelVerifyHanlderResult;
/**
* 基础校验工具类
*
* @author JEECG
* @date 2014年6月23日 下午11:10:12
*/
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);
}
}

View File

@@ -0,0 +1,81 @@
/**
* Copyright 2013-2015 JEECG (jeecgos@163.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jeecgframework.poi.excel.imports.verifys;
import org.apache.commons.lang3.StringUtils;
import org.jeecgframework.poi.excel.entity.params.ExcelVerifyEntity;
import org.jeecgframework.poi.excel.entity.result.ExcelVerifyHanlderResult;
import org.jeecgframework.poi.handler.inter.IExcelVerifyHandler;
/**
* 校验服务
*
* @author JEECG
* @date 2014年6月29日 下午4:37:56
*/
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 titleString
* @param verify
* @param excelVerifyHandler
*/
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;
}
}

View File

@@ -0,0 +1,62 @@
/**
* Copyright 2013-2015 JEECG (jeecgos@163.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jeecgframework.poi.exception.excel;
import org.jeecgframework.poi.exception.excel.enums.ExcelExportEnum;
/**
* 导出异常
*
* @author JEECG
* @date 2014年6月19日 下午10:56:18
*/
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;
}
}

View File

@@ -0,0 +1,62 @@
/**
* Copyright 2013-2015 JEECG (jeecgos@163.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jeecgframework.poi.exception.excel;
import org.jeecgframework.poi.exception.excel.enums.ExcelImportEnum;
/**
* 导入异常
*
* @author JEECG
* @date 2014年6月29日 下午2:23:43
*/
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;
}
}

View File

@@ -0,0 +1,42 @@
/**
* Copyright 2013-2015 JEECG (jeecgos@163.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jeecgframework.poi.exception.excel.enums;
/**
* 导出异常类型枚举
*
* @author JEECG
* @date 2014年6月19日 下午10:59:51
*/
public enum ExcelExportEnum {
PARAMETER_ERROR("Excel 导出 参数错误"), EXPORT_ERROR("Excel导出错误"),TEMPLATE_ERROR ("Excel 模板错误");;
private String msg;
ExcelExportEnum(String msg) {
this.msg = msg;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}

View File

@@ -0,0 +1,42 @@
/**
* Copyright 2013-2015 JEECG (jeecgos@163.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jeecgframework.poi.exception.excel.enums;
/**
* 导出异常类型枚举
*
* @author JEECG
* @date 2014年6月19日 下午10:59:51
*/
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;
}
}

View File

@@ -0,0 +1,42 @@
/**
* Copyright 2013-2015 JEECG (jeecgos@163.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jeecgframework.poi.exception.word;
import org.jeecgframework.poi.exception.word.enmus.WordExportEnum;
/**
* word导出异常
*
* @author JEECG
* @date 2014年8月9日 下午10:32:51
*/
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());
}
}

View File

@@ -0,0 +1,42 @@
/**
* Copyright 2013-2015 JEECG (jeecgos@163.com)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jeecgframework.poi.exception.word.enmus;
/**
* 导出异常枚举
*
* @author JEECG
* @date 2014年8月9日 下午10:34:58
*/
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;
}
}

Some files were not shown because too many files have changed in this diff Show More