From 5b2e39f3ca207d8a02cdb772fa5bbbe3b71967f8 Mon Sep 17 00:00:00 2001
From: RuoYi <yzz_ivy@163.com>
Date: 星期三, 11 八月 2021 10:08:12 +0800
Subject: [PATCH] Excel注解支持Image图片导入
---
src/main/java/com/ruoyi/common/utils/file/FileUtils.java | 97 ++++++++++---
src/main/java/com/ruoyi/framework/config/RuoYiConfig.java | 8 +
src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java | 253 ++++++++++++++++++++++++++---------
src/main/java/com/ruoyi/common/utils/file/FileUploadUtils.java | 4
4 files changed, 271 insertions(+), 91 deletions(-)
diff --git a/src/main/java/com/ruoyi/common/utils/file/FileUploadUtils.java b/src/main/java/com/ruoyi/common/utils/file/FileUploadUtils.java
index cb1474f..afed94d 100644
--- a/src/main/java/com/ruoyi/common/utils/file/FileUploadUtils.java
+++ b/src/main/java/com/ruoyi/common/utils/file/FileUploadUtils.java
@@ -127,7 +127,7 @@
return fileName;
}
- private static final File getAbsoluteFile(String uploadDir, String fileName) throws IOException
+ public static final File getAbsoluteFile(String uploadDir, String fileName) throws IOException
{
File desc = new File(uploadDir + File.separator + fileName);
@@ -141,7 +141,7 @@
return desc;
}
- private static final String getPathFileName(String uploadDir, String fileName) throws IOException
+ public static final String getPathFileName(String uploadDir, String fileName) throws IOException
{
int dirLastIndex = RuoYiConfig.getProfile().length() + 1;
String currentDir = StringUtils.substring(uploadDir, dirLastIndex);
diff --git a/src/main/java/com/ruoyi/common/utils/file/FileUtils.java b/src/main/java/com/ruoyi/common/utils/file/FileUtils.java
index dfdf9e9..4bf910e 100644
--- a/src/main/java/com/ruoyi/common/utils/file/FileUtils.java
+++ b/src/main/java/com/ruoyi/common/utils/file/FileUtils.java
@@ -3,6 +3,7 @@
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
@@ -10,8 +11,12 @@
import java.nio.charset.StandardCharsets;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.ArrayUtils;
+import com.ruoyi.common.utils.DateUtils;
+import com.ruoyi.common.utils.IdUtils;
import com.ruoyi.common.utils.StringUtils;
+import com.ruoyi.framework.config.RuoYiConfig;
/**
* 鏂囦欢澶勭悊宸ュ叿绫�
@@ -53,29 +58,48 @@
}
finally
{
- if (os != null)
- {
- try
- {
- os.close();
- }
- catch (IOException e1)
- {
- e1.printStackTrace();
- }
- }
- if (fis != null)
- {
- try
- {
- fis.close();
- }
- catch (IOException e1)
- {
- e1.printStackTrace();
- }
- }
+ IOUtils.close(os);
+ IOUtils.close(fis);
}
+ }
+
+ /**
+ * 鍐欐暟鎹埌鏂囦欢涓�
+ *
+ * @param data 鏁版嵁
+ * @return 鐩爣鏂囦欢
+ * @throws IOException IO寮傚父
+ */
+ public static String writeImportBytes(byte[] data) throws IOException
+ {
+ return writeBytes(data, RuoYiConfig.getImportPath());
+ }
+
+ /**
+ * 鍐欐暟鎹埌鏂囦欢涓�
+ *
+ * @param data 鏁版嵁
+ * @param uploadDir 鐩爣鏂囦欢
+ * @return 鐩爣鏂囦欢
+ * @throws IOException IO寮傚父
+ */
+ public static String writeBytes(byte[] data, String uploadDir) throws IOException
+ {
+ FileOutputStream fos = null;
+ String pathName = "";
+ try
+ {
+ String extension = getFileExtendName(data);
+ pathName = DateUtils.datePath() + "/" + IdUtils.fastUUID() + "." + extension;
+ File file = FileUploadUtils.getAbsoluteFile(uploadDir, pathName);
+ fos = new FileOutputStream(file);
+ fos.write(data);
+ }
+ finally
+ {
+ IOUtils.close(fos);
+ }
+ return FileUploadUtils.getPathFileName(uploadDir, pathName);
}
/**
@@ -200,4 +224,33 @@
String encode = URLEncoder.encode(s, StandardCharsets.UTF_8.toString());
return encode.replaceAll("\\+", "%20");
}
+
+ /**
+ * 鑾峰彇鍥惧儚鍚庣紑
+ *
+ * @param photoByte 鍥惧儚鏁版嵁
+ * @return 鍚庣紑鍚�
+ */
+ public static String getFileExtendName(byte[] photoByte)
+ {
+ String strFileExtendName = "jpg";
+ if ((photoByte[0] == 71) && (photoByte[1] == 73) && (photoByte[2] == 70) && (photoByte[3] == 56)
+ && ((photoByte[4] == 55) || (photoByte[4] == 57)) && (photoByte[5] == 97))
+ {
+ strFileExtendName = "gif";
+ }
+ else if ((photoByte[6] == 74) && (photoByte[7] == 70) && (photoByte[8] == 73) && (photoByte[9] == 70))
+ {
+ strFileExtendName = "jpg";
+ }
+ else if ((photoByte[0] == 66) && (photoByte[1] == 77))
+ {
+ strFileExtendName = "bmp";
+ }
+ else if ((photoByte[1] == 80) && (photoByte[2] == 78) && (photoByte[3] == 71))
+ {
+ strFileExtendName = "png";
+ }
+ return strFileExtendName;
+ }
}
diff --git a/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java b/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java
index aac6ab1..11bd63e 100644
--- a/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java
+++ b/src/main/java/com/ruoyi/common/utils/poi/ExcelUtil.java
@@ -18,6 +18,8 @@
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
+import javax.servlet.http.HttpServletResponse;
+import org.apache.poi.ooxml.POIXMLDocumentPart;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
@@ -32,15 +34,23 @@
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
+import org.apache.poi.ss.usermodel.PictureData;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.ss.util.CellRangeAddressList;
+import org.apache.poi.util.IOUtils;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
import org.apache.poi.xssf.usermodel.XSSFDataValidation;
+import org.apache.poi.xssf.usermodel.XSSFDrawing;
+import org.apache.poi.xssf.usermodel.XSSFPicture;
+import org.apache.poi.xssf.usermodel.XSSFShape;
+import org.apache.poi.xssf.usermodel.XSSFSheet;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
+import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.CTMarker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.ruoyi.common.core.text.Convert;
@@ -49,6 +59,7 @@
import com.ruoyi.common.utils.DictUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.FileTypeUtils;
+import com.ruoyi.common.utils.file.FileUtils;
import com.ruoyi.common.utils.file.ImageUtils;
import com.ruoyi.common.utils.reflect.ReflectUtils;
import com.ruoyi.framework.aspectj.lang.annotation.Excel;
@@ -116,12 +127,12 @@
* 缁熻鍒楄〃
*/
private Map<Integer, Double> statistics = new HashMap<Integer, Double>();
-
+
/**
* 鏁板瓧鏍煎紡
*/
private static final DecimalFormat DOUBLE_FORMAT = new DecimalFormat("######0.00");
-
+
/**
* 瀹炰綋瀵硅薄
*/
@@ -168,24 +179,15 @@
this.type = Type.IMPORT;
this.wb = WorkbookFactory.create(is);
List<T> list = new ArrayList<T>();
- Sheet sheet = null;
- if (StringUtils.isNotEmpty(sheetName))
- {
- // 濡傛灉鎸囧畾sheet鍚�,鍒欏彇鎸囧畾sheet涓殑鍐呭.
- sheet = wb.getSheet(sheetName);
- }
- else
- {
- // 濡傛灉浼犲叆鐨剆heet鍚嶄笉瀛樺湪鍒欓粯璁ゆ寚鍚戠1涓猻heet.
- sheet = wb.getSheetAt(0);
- }
-
+ // 濡傛灉鎸囧畾sheet鍚�,鍒欏彇鎸囧畾sheet涓殑鍐呭 鍚﹀垯榛樿鎸囧悜绗�1涓猻heet
+ Sheet sheet = StringUtils.isNotEmpty(sheetName) ? wb.getSheet(sheetName) : wb.getSheetAt(0);
if (sheet == null)
{
throw new IOException("鏂囦欢sheet涓嶅瓨鍦�");
}
-
- int rows = sheet.getPhysicalNumberOfRows();
+ Map<String, PictureData> pictures = getSheetPictrues((XSSFSheet) sheet, (XSSFWorkbook) wb);
+ // 鑾峰彇鏈�鍚庝竴涓潪绌鸿鐨勮涓嬫爣锛屾瘮濡傛�昏鏁颁负n锛屽垯杩斿洖鐨勪负n-1
+ int rows = sheet.getLastRowNum();
if (rows > 0)
{
@@ -225,10 +227,15 @@
}
}
}
- for (int i = 1; i < rows; i++)
+ for (int i = 1; i <= rows; i++)
{
// 浠庣2琛屽紑濮嬪彇鏁版嵁,榛樿绗竴琛屾槸琛ㄥご.
Row row = sheet.getRow(i);
+ // 鍒ゆ柇褰撳墠琛屾槸鍚︽槸绌鸿
+ if (isRowEmpty(row))
+ {
+ continue;
+ }
T entity = null;
for (Map.Entry<Integer, Field> entry : fieldsMap.entrySet())
{
@@ -311,6 +318,20 @@
{
val = reverseDictByExp(Convert.toStr(val), attr.dictType(), attr.separator());
}
+ else if (ColumnType.IMAGE == attr.cellType())
+ {
+ if (StringUtils.isNull(pictures))
+ {
+ val = "";
+ }
+ PictureData image = pictures.get(row.getRowNum() + "_" + entry.getKey());
+ if (image == null)
+ {
+ val = "";
+ }
+ byte[] data = image.getData();
+ val = FileUtils.writeImportBytes(data);
+ }
ReflectUtils.invokeSetter(entity, propertyName, val);
}
}
@@ -336,6 +357,23 @@
/**
* 瀵筶ist鏁版嵁婧愬皢鍏堕噷闈㈢殑鏁版嵁瀵煎叆鍒癳xcel琛ㄥ崟
*
+ * @param response 杩斿洖鏁版嵁
+ * @param list 瀵煎嚭鏁版嵁闆嗗悎
+ * @param sheetName 宸ヤ綔琛ㄧ殑鍚嶇О
+ * @return 缁撴灉
+ * @throws IOException
+ */
+ public void exportExcel(HttpServletResponse response, List<T> list, String sheetName) throws IOException
+ {
+ response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
+ response.setCharacterEncoding("utf-8");
+ this.init(list, sheetName, Type.EXPORT);
+ exportExcel(response.getOutputStream());
+ }
+
+ /**
+ * 瀵筶ist鏁版嵁婧愬皢鍏堕噷闈㈢殑鏁版嵁瀵煎叆鍒癳xcel琛ㄥ崟
+ *
* @param sheetName 宸ヤ綔琛ㄧ殑鍚嶇О
* @return 缁撴灉
*/
@@ -348,6 +386,43 @@
/**
* 瀵筶ist鏁版嵁婧愬皢鍏堕噷闈㈢殑鏁版嵁瀵煎叆鍒癳xcel琛ㄥ崟
*
+ * @param sheetName 宸ヤ綔琛ㄧ殑鍚嶇О
+ * @return 缁撴灉
+ */
+ public void importTemplateExcel(HttpServletResponse response, String sheetName) throws IOException
+ {
+ response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
+ response.setCharacterEncoding("utf-8");
+ this.init(null, sheetName, Type.IMPORT);
+ exportExcel(response.getOutputStream());
+ }
+
+ /**
+ * 瀵筶ist鏁版嵁婧愬皢鍏堕噷闈㈢殑鏁版嵁瀵煎叆鍒癳xcel琛ㄥ崟
+ *
+ * @return 缁撴灉
+ */
+ public void exportExcel(OutputStream out)
+ {
+ try
+ {
+ writeSheet();
+ wb.write(out);
+ }
+ catch (Exception e)
+ {
+ log.error("瀵煎嚭Excel寮傚父{}", e.getMessage());
+ }
+ finally
+ {
+ IOUtils.closeQuietly(wb);
+ IOUtils.closeQuietly(out);
+ }
+ }
+
+ /**
+ * 瀵筶ist鏁版嵁婧愬皢鍏堕噷闈㈢殑鏁版嵁瀵煎叆鍒癳xcel琛ㄥ崟
+ *
* @return 缁撴灉
*/
public AjaxResult exportExcel()
@@ -355,27 +430,7 @@
OutputStream out = null;
try
{
- // 鍙栧嚭涓�鍏辨湁澶氬皯涓猻heet.
- double sheetNo = Math.ceil(list.size() / sheetSize);
- for (int index = 0; index <= sheetNo; index++)
- {
- createSheet(sheetNo, index);
-
- // 浜х敓涓�琛�
- Row row = sheet.createRow(0);
- int column = 0;
- // 鍐欏叆鍚勪釜瀛楁鐨勫垪澶村悕绉�
- for (Object[] os : fields)
- {
- Excel excel = (Excel) os[1];
- this.createCell(excel, row, column++);
- }
- if (Type.EXPORT.equals(type))
- {
- fillExcelData(index, row);
- addStatisticsRow();
- }
- }
+ writeSheet();
String filename = encodingFilename(sheetName);
out = new FileOutputStream(getAbsoluteFile(filename));
wb.write(out);
@@ -388,27 +443,35 @@
}
finally
{
- if (wb != null)
+ IOUtils.closeQuietly(wb);
+ IOUtils.closeQuietly(out);
+ }
+ }
+
+ /**
+ * 鍒涘缓鍐欏叆鏁版嵁鍒癝heet
+ */
+ public void writeSheet()
+ {
+ // 鍙栧嚭涓�鍏辨湁澶氬皯涓猻heet.
+ double sheetNo = Math.ceil(list.size() / sheetSize);
+ for (int index = 0; index <= sheetNo; index++)
+ {
+ createSheet(sheetNo, index);
+
+ // 浜х敓涓�琛�
+ Row row = sheet.createRow(0);
+ int column = 0;
+ // 鍐欏叆鍚勪釜瀛楁鐨勫垪澶村悕绉�
+ for (Object[] os : fields)
{
- try
- {
- wb.close();
- }
- catch (IOException e1)
- {
- e1.printStackTrace();
- }
+ Excel excel = (Excel) os[1];
+ this.createCell(excel, row, column++);
}
- if (out != null)
+ if (Type.EXPORT.equals(type))
{
- try
- {
- out.close();
- }
- catch (IOException e1)
- {
- e1.printStackTrace();
- }
+ fillExcelData(index, row);
+ addStatisticsRow();
}
}
}
@@ -480,7 +543,7 @@
headerFont.setColor(IndexedColors.WHITE.getIndex());
style.setFont(headerFont);
styles.put("header", style);
-
+
style = wb.createCellStyle();
style.setAlignment(HorizontalAlignment.CENTER);
style.setVerticalAlignment(VerticalAlignment.CENTER);
@@ -537,12 +600,14 @@
}
else if (ColumnType.NUMERIC == attr.cellType())
{
- cell.setCellValue(StringUtils.contains(Convert.toStr(value), ".") ? Convert.toDouble(value) : Convert.toInt(value));
+ if (StringUtils.isNotNull(value))
+ {
+ cell.setCellValue(StringUtils.contains(Convert.toStr(value), ".") ? Convert.toDouble(value) : Convert.toInt(value));
+ }
}
else if (ColumnType.IMAGE == attr.cellType())
{
- ClientAnchor anchor = new XSSFClientAnchor(0, 0, 0, 0, (short) cell.getColumnIndex(), cell.getRow().getRowNum(), (short) (cell.getColumnIndex() + 1),
- cell.getRow().getRowNum() + 1);
+ ClientAnchor anchor = new XSSFClientAnchor(0, 0, 0, 0, (short) cell.getColumnIndex(), cell.getRow().getRowNum(), (short) (cell.getColumnIndex() + 1), cell.getRow().getRowNum() + 1);
String imagePath = Convert.toStr(value);
if (StringUtils.isNotEmpty(imagePath))
{
@@ -552,7 +617,7 @@
}
}
}
-
+
/**
* 鑾峰彇鐢诲竷
*/
@@ -795,7 +860,7 @@
}
return StringUtils.stripEnd(propertyString.toString(), separator);
}
-
+
/**
* 瑙f瀽瀛楀吀鍊�
*
@@ -821,7 +886,7 @@
{
return DictUtils.getDictValue(dictType, dictLabel, separator);
}
-
+
/**
* 鍚堣缁熻淇℃伅
*/
@@ -852,13 +917,12 @@
{
if (statistics.size() > 0)
{
- Cell cell = null;
Row row = sheet.createRow(sheet.getLastRowNum() + 1);
Set<Integer> keys = statistics.keySet();
- cell = row.createCell(0);
+ Cell cell = row.createCell(0);
cell.setCellStyle(styles.get("total"));
cell.setCellValue("鍚堣");
-
+
for (Integer key : keys)
{
cell = row.createCell(key);
@@ -976,7 +1040,7 @@
this.fields = this.fields.stream().sorted(Comparator.comparing(objects -> ((Excel) objects[1]).sort())).collect(Collectors.toList());
this.maxHeight = getRowHeight();
}
-
+
/**
* 鏍规嵁娉ㄨВ鑾峰彇鏈�澶ц楂�
*/
@@ -1090,4 +1154,59 @@
}
return val;
}
+
+ /**
+ * 鍒ゆ柇鏄惁鏄┖琛�
+ *
+ * @param row 鍒ゆ柇鐨勮
+ * @return
+ */
+ private boolean isRowEmpty(Row row)
+ {
+ if (row == null)
+ {
+ return true;
+ }
+ for (int i = row.getFirstCellNum(); i < row.getLastCellNum(); i++)
+ {
+ Cell cell = row.getCell(i);
+ if (cell != null && cell.getCellType() != CellType.BLANK)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * 鑾峰彇Excel鍥剧墖
+ *
+ * @param sheet 褰撳墠sheet瀵硅薄
+ * @param workbook 宸ヤ綔绨垮璞�
+ * @return Map key:鍥剧墖鍗曞厓鏍肩储寮曪紙1_1锛塖tring锛寁alue:鍥剧墖娴丳ictureData
+ */
+ public static Map<String, PictureData> getSheetPictrues(XSSFSheet sheet, XSSFWorkbook workbook)
+ {
+ Map<String, PictureData> sheetIndexPicMap = new HashMap<String, PictureData>();
+ for (POIXMLDocumentPart dr : sheet.getRelations())
+ {
+ if (dr instanceof XSSFDrawing)
+ {
+ XSSFDrawing drawing = (XSSFDrawing) dr;
+ List<XSSFShape> shapes = drawing.getShapes();
+ for (XSSFShape shape : shapes)
+ {
+ if (shape instanceof XSSFPicture)
+ {
+ XSSFPicture pic = (XSSFPicture) shape;
+ XSSFClientAnchor anchor = pic.getPreferredSize();
+ CTMarker ctMarker = anchor.getFrom();
+ String picIndex = ctMarker.getRow() + "_" + ctMarker.getCol();
+ sheetIndexPicMap.put(picIndex, pic.getPictureData());
+ }
+ }
+ }
+ }
+ return sheetIndexPicMap;
+ }
}
\ No newline at end of file
diff --git a/src/main/java/com/ruoyi/framework/config/RuoYiConfig.java b/src/main/java/com/ruoyi/framework/config/RuoYiConfig.java
index 1f6e20a..0f2a82d 100644
--- a/src/main/java/com/ruoyi/framework/config/RuoYiConfig.java
+++ b/src/main/java/com/ruoyi/framework/config/RuoYiConfig.java
@@ -91,6 +91,14 @@
}
/**
+ * 鑾峰彇瀵煎叆涓婁紶璺緞
+ */
+ public static String getImportPath()
+ {
+ return getProfile() + "/import";
+ }
+
+ /**
* 鑾峰彇澶村儚涓婁紶璺緞
*/
public static String getAvatarPath()
--
Gitblit v1.9.3