Excel注解支持Image图片导出
This commit is contained in:
		| @@ -149,7 +149,7 @@ public @interface Excel | ||||
|  | ||||
|     public enum ColumnType | ||||
|     { | ||||
|         NUMERIC(0), STRING(1); | ||||
|         NUMERIC(0), STRING(1), IMAGE(2); | ||||
|         private final int value; | ||||
|  | ||||
|         ColumnType(int value) | ||||
|   | ||||
| @@ -44,4 +44,33 @@ public class FileTypeUtils | ||||
|         } | ||||
|         return fileName.substring(separatorIndex + 1).toLowerCase(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 获取文件类型 | ||||
|      *  | ||||
|      * @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; | ||||
|     } | ||||
| } | ||||
| @@ -0,0 +1,100 @@ | ||||
| package com.ruoyi.common.utils.file; | ||||
|  | ||||
| import java.io.ByteArrayInputStream; | ||||
| import java.io.ByteArrayOutputStream; | ||||
| import java.io.FileInputStream; | ||||
| import java.io.InputStream; | ||||
| import java.net.URL; | ||||
| import java.net.URLConnection; | ||||
| import java.util.Arrays; | ||||
| import org.apache.poi.util.IOUtils; | ||||
| import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | ||||
| import com.ruoyi.common.config.RuoYiConfig; | ||||
| import com.ruoyi.common.constant.Constants; | ||||
| import com.ruoyi.common.utils.StringUtils; | ||||
|  | ||||
| /** | ||||
|  * 图片处理工具类 | ||||
|  * | ||||
|  * @author ruoyi | ||||
|  */ | ||||
| public class ImageUtils | ||||
| { | ||||
|     private static final Logger log = LoggerFactory.getLogger(ImageUtils.class); | ||||
|  | ||||
|     public static byte[] getImage(String imagePath) | ||||
|     { | ||||
|         InputStream is = getFile(imagePath); | ||||
|         try | ||||
|         { | ||||
|             return IOUtils.toByteArray(is); | ||||
|         } | ||||
|         catch (Exception e) | ||||
|         { | ||||
|             log.error("图片加载异常 {}", e); | ||||
|             return null; | ||||
|         } | ||||
|         finally | ||||
|         { | ||||
|             IOUtils.closeQuietly(is); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public static InputStream getFile(String imagePath) | ||||
|     { | ||||
|         try | ||||
|         { | ||||
|             byte[] result = readFile(imagePath); | ||||
|             result = Arrays.copyOf(result, result.length); | ||||
|             return new ByteArrayInputStream(result); | ||||
|         } | ||||
|         catch (Exception e) | ||||
|         { | ||||
|             log.error("获取图片异常 {}", e); | ||||
|         } | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 读取文件为字节数据 | ||||
|      *  | ||||
|      * @param key 地址 | ||||
|      * @return 字节数据 | ||||
|      */ | ||||
|     public static byte[] readFile(String url) | ||||
|     { | ||||
|         InputStream in = null; | ||||
|         ByteArrayOutputStream baos = null; | ||||
|         try | ||||
|         { | ||||
|             if (url.startsWith("http")) | ||||
|             { | ||||
|                 // 网络地址 | ||||
|                 URL urlObj = new URL(url); | ||||
|                 URLConnection urlConnection = urlObj.openConnection(); | ||||
|                 urlConnection.setConnectTimeout(30 * 1000); | ||||
|                 urlConnection.setReadTimeout(60 * 1000); | ||||
|                 urlConnection.setDoInput(true); | ||||
|                 in = urlConnection.getInputStream(); | ||||
|             } | ||||
|             else | ||||
|             { | ||||
|                 // 本机地址 | ||||
|                 String localPath = RuoYiConfig.getProfile(); | ||||
|                 String downloadPath = localPath + StringUtils.substringAfter(url, Constants.RESOURCE_PREFIX); | ||||
|                 in = new FileInputStream(downloadPath); | ||||
|             } | ||||
|             return IOUtils.toByteArray(in); | ||||
|         } | ||||
|         catch (Exception e) | ||||
|         { | ||||
|             log.error("获取文件路径异常 {}", e); | ||||
|             return null; | ||||
|         } | ||||
|         finally | ||||
|         { | ||||
|             IOUtils.closeQuietly(baos); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -22,10 +22,12 @@ import org.apache.poi.ss.usermodel.BorderStyle; | ||||
| import org.apache.poi.ss.usermodel.Cell; | ||||
| import org.apache.poi.ss.usermodel.CellStyle; | ||||
| import org.apache.poi.ss.usermodel.CellType; | ||||
| import org.apache.poi.ss.usermodel.ClientAnchor; | ||||
| import org.apache.poi.ss.usermodel.DataValidation; | ||||
| import org.apache.poi.ss.usermodel.DataValidationConstraint; | ||||
| import org.apache.poi.ss.usermodel.DataValidationHelper; | ||||
| import org.apache.poi.ss.usermodel.DateUtil; | ||||
| import org.apache.poi.ss.usermodel.Drawing; | ||||
| import org.apache.poi.ss.usermodel.FillPatternType; | ||||
| import org.apache.poi.ss.usermodel.Font; | ||||
| import org.apache.poi.ss.usermodel.HorizontalAlignment; | ||||
| @@ -37,6 +39,7 @@ 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.xssf.streaming.SXSSFWorkbook; | ||||
| import org.apache.poi.xssf.usermodel.XSSFClientAnchor; | ||||
| import org.apache.poi.xssf.usermodel.XSSFDataValidation; | ||||
| import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | ||||
| @@ -51,6 +54,8 @@ import com.ruoyi.common.exception.CustomException; | ||||
| import com.ruoyi.common.utils.DateUtils; | ||||
| 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.ImageUtils; | ||||
| import com.ruoyi.common.utils.reflect.ReflectUtils; | ||||
|  | ||||
| /** | ||||
| @@ -102,16 +107,21 @@ public class ExcelUtil<T> | ||||
|      */ | ||||
|     private List<Object[]> fields; | ||||
|  | ||||
|     /** | ||||
|      * 最大高度 | ||||
|      */ | ||||
|     private short maxHeight; | ||||
|  | ||||
|     /** | ||||
|      * 统计列表 | ||||
|      */ | ||||
|     private Map<Integer, Double> statistics = new HashMap<Integer, Double>(); | ||||
|  | ||||
|      | ||||
|     /** | ||||
|      * 数字格式 | ||||
|      */ | ||||
|     private static final DecimalFormat DOUBLE_FORMAT = new DecimalFormat("######0.00"); | ||||
|  | ||||
|      | ||||
|     /** | ||||
|      * 实体对象 | ||||
|      */ | ||||
| @@ -239,7 +249,15 @@ public class ExcelUtil<T> | ||||
|                         } | ||||
|                         else | ||||
|                         { | ||||
|                             val = Convert.toStr(val); | ||||
|                             String dateFormat = field.getAnnotation(Excel.class).dateFormat(); | ||||
|                             if (StringUtils.isNotEmpty(dateFormat)) | ||||
|                             { | ||||
|                                 val = DateUtils.parseDateToStr(dateFormat, (Date) val); | ||||
|                             } | ||||
|                             else | ||||
|                             { | ||||
|                                 val = Convert.toStr(val); | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                     else if ((Integer.TYPE == fieldType || Integer.class == fieldType) && StringUtils.isNumeric(Convert.toStr(val))) | ||||
| @@ -521,6 +539,47 @@ public class ExcelUtil<T> | ||||
|         { | ||||
|             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); | ||||
|             String imagePath = Convert.toStr(value); | ||||
|             if (StringUtils.isNotEmpty(imagePath)) | ||||
|             { | ||||
|                 byte[] data = ImageUtils.getImage(imagePath); | ||||
|                 getDrawingPatriarch(cell.getSheet()).createPicture(anchor, | ||||
|                         cell.getSheet().getWorkbook().addPicture(data, getImageType(data))); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     /** | ||||
|      * 获取画布 | ||||
|      */ | ||||
|     public static Drawing<?> getDrawingPatriarch(Sheet sheet) | ||||
|     { | ||||
|         if (sheet.getDrawingPatriarch() == null) | ||||
|         { | ||||
|             sheet.createDrawingPatriarch(); | ||||
|         } | ||||
|         return sheet.getDrawingPatriarch(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 获取图片类型,设置图片插入类型 | ||||
|      */ | ||||
|     public int getImageType(byte[] value) | ||||
|     { | ||||
|         String type = FileTypeUtils.getFileExtendName(value); | ||||
|         if ("JPG".equalsIgnoreCase(type)) | ||||
|         { | ||||
|             return Workbook.PICTURE_TYPE_JPEG; | ||||
|         } | ||||
|         else if ("PNG".equalsIgnoreCase(type)) | ||||
|         { | ||||
|             return Workbook.PICTURE_TYPE_PNG; | ||||
|         } | ||||
|         return Workbook.PICTURE_TYPE_JPEG; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
| @@ -536,7 +595,6 @@ public class ExcelUtil<T> | ||||
|         { | ||||
|             // 设置列宽 | ||||
|             sheet.setColumnWidth(column, (int) ((attr.width() + 0.72) * 256)); | ||||
|             row.setHeight((short) (attr.height() * 20)); | ||||
|         } | ||||
|         // 如果设置了提示信息则鼠标放上去提示. | ||||
|         if (StringUtils.isNotEmpty(attr.prompt())) | ||||
| @@ -561,7 +619,7 @@ public class ExcelUtil<T> | ||||
|         try | ||||
|         { | ||||
|             // 设置行高 | ||||
|             row.setHeight((short) (attr.height() * 20)); | ||||
|             row.setHeight(maxHeight); | ||||
|             // 根据Excel中设置情况决定是否导出,有些情况需要保持为空,希望用户填写这一列. | ||||
|             if (attr.isExport()) | ||||
|             { | ||||
| @@ -737,7 +795,7 @@ public class ExcelUtil<T> | ||||
|         } | ||||
|         return StringUtils.stripEnd(propertyString.toString(), separator); | ||||
|     } | ||||
|  | ||||
|      | ||||
|     /** | ||||
|      * 解析字典值 | ||||
|      *  | ||||
| @@ -763,7 +821,7 @@ public class ExcelUtil<T> | ||||
|     { | ||||
|         return DictUtils.getDictValue(dictType, dictLabel, separator); | ||||
|     } | ||||
|  | ||||
|      | ||||
|     /** | ||||
|      * 合计统计信息 | ||||
|      */ | ||||
| @@ -800,7 +858,7 @@ public class ExcelUtil<T> | ||||
|             cell = row.createCell(0); | ||||
|             cell.setCellStyle(styles.get("total")); | ||||
|             cell.setCellValue("合计"); | ||||
|  | ||||
|              | ||||
|             for (Integer key : keys) | ||||
|             { | ||||
|                 cell = row.createCell(key); | ||||
| @@ -916,6 +974,21 @@ public class ExcelUtil<T> | ||||
|             } | ||||
|         } | ||||
|         this.fields = this.fields.stream().sorted(Comparator.comparing(objects -> ((Excel) objects[1]).sort())).collect(Collectors.toList()); | ||||
|         this.maxHeight = getRowHeight(); | ||||
|     } | ||||
|      | ||||
|     /** | ||||
|      * 根据注解获取最大行高 | ||||
|      */ | ||||
|     public short getRowHeight() | ||||
|     { | ||||
|         double maxHeight = 0; | ||||
|         for (Object[] os : this.fields) | ||||
|         { | ||||
|             Excel excel = (Excel) os[1]; | ||||
|             maxHeight = maxHeight > excel.height() ? maxHeight : excel.height(); | ||||
|         } | ||||
|         return (short) (maxHeight * 20); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|   | ||||
		Reference in New Issue
	
	Block a user