阅读量:0
1. Graphics2D 图片绘写
我的需求是在图片的固定位置绘写固定数值所以比较简单
ImageIO.write(read, “png”, destImageFile); png是文件类型,我这里是固定的
public class ImageText { private String data; private float x; private float y; private Font font; private Color color; public ImageText(String data, Color color) { this.data = data; this.color = color; } public ImageText(String data, float x, float y, Font font, Color color) { this.data = data; this.x = x; this.y = y; this.font = font; this.color = color; } public ImageText() {} } public class DrawUtil { private static final Logger log = LoggerFactory.getLogger(DrawUtil.class); /** * JAVA添加文字水印 * @param srcImageFile 目标图片 * @param destImageFile 结果图片 * @param imageTextList 文字及坐标集合 * @return */ public static boolean drawText(InputStream srcImageFile, File destImageFile, ArrayList<ImageText> imageTextList) { try { //使用ImageIO的read方法读取图片 BufferedImage read = ImageIO.read(srcImageFile); Graphics2D graphics = read.createGraphics(); // 设置“抗锯齿”的属性 graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); for (ImageText imageText : imageTextList) { // 设置字体类型和大小 graphics.setFont(imageText.getFont()); // 设置颜色 graphics.setColor(imageText.getColor()); // 添加文字 graphics.drawString( imageText.getData(), imageText.getX(), imageText.getY()); } //回收 Graphics 释放资源 graphics.dispose(); //获取到文件的后缀名 // String fileName = IdUtils.fastSimpleUUID()+".png"; // String formatName = fileName.substring(fileName.lastIndexOf(".") + 1); //使用ImageIO的write方法进行输出 ImageIO.write(read, "png", destImageFile); } catch (IOException e) { log.error(" watermarkText 图文绘制异常!", e); } return true; } }
2. 获取自定义字体
字体文件存放在resources/static/OPPOSans-B-2.ttf
fontFile.getInputStream() 使用文件流不然报错 找不到文件
fontFile.getFile()本地执行成功但是上服务器就会报错
/** * 获取字体文件 */ public static Font getFont(float fontSize) { Font font = null; ClassPathResource fontFile = new ClassPathResource("/static/OPPOSans-B-2.ttf"); Font tempFont = null; try (InputStream in=fontFile.getInputStream();){ tempFont = Font.createFont(Font.TRUETYPE_FONT, in); } catch (FontFormatException | IOException e) { log.error(" OPPOSans 字体文件获取失败!", e); } assert tempFont != null; font = tempFont.deriveFont(fontSize); return font; }
3. 将File转换MultipartFile
主要是公共的上传文件组件一般使用MultipartFile类型,所有做个转换
MultipartFileDto multipartFileDto = new MultipartFileDto(tempFile.getName(), tempFile.getName(), “image/png”, fileInputStream);
“image/png”, 配置是为了上传MinIO返回的url是直接预览,而不是附件下载
整体图片绘制逻辑是:
先读取resources下的固定图片文件,同时创建临时图片文件作为输出对象,将绘制数据和两个文件相关对象传递给drawText绘画。然后 临时文件将File转换MultipartFile上传MinIO返回url保存,删除临时文件
import org.springframework.util.FileCopyUtils; import org.springframework.web.multipart.MultipartFile; import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.io.InputStream; public class MultipartFileDto implements MultipartFile { private final String name; private String originalFilename; private String contentType; private final byte[] content; public MultipartFileDto(String name, byte[] content) { this(name, "", null, content); } public MultipartFileDto(String name, InputStream contentStream) throws IOException { this(name, "", null, FileCopyUtils.copyToByteArray(contentStream)); } public MultipartFileDto(String name, String originalFilename, String contentType, byte[] content) { this.name = name; this.originalFilename = (originalFilename != null ? originalFilename : ""); this.contentType = contentType; this.content = (content != null ? content : new byte[0]); } public MultipartFileDto(String name, String originalFilename, String contentType, InputStream contentStream) throws IOException { this(name, originalFilename, contentType, FileCopyUtils.copyToByteArray(contentStream)); } @Override public String getName() { return this.name; } @Override public String getOriginalFilename() { return this.originalFilename; } @Override public String getContentType() { return this.contentType; } @Override public boolean isEmpty() { return (this.content.length == 0); } @Override public long getSize() { return this.content.length; } @Override public byte[] getBytes() throws IOException { return this.content; } @Override public InputStream getInputStream() throws IOException { return new ByteArrayInputStream(this.content); } @Override public void transferTo(File dest) throws IOException, IllegalStateException { FileCopyUtils.copy(this.content, dest); } } /** * 新增图片消息 */ private void addImgMsg(JcWechatAccount account, File tempFile) { //上传图片 try (FileInputStream fileInputStream = new FileInputStream(tempFile);) { //application/octet-stream 告诉浏览器这是一个附件,浏览器会直接进行下载,而不是预览,只有image/png或者image/jpeg这种的的才会进行预览 MultipartFileDto multipartFileDto = new MultipartFileDto(tempFile.getName(), tempFile.getName(), "image/png", fileInputStream); String upload = commonController.upload(multipartFileDto); addImgMsgText(account, upload,MessageType.IMAGE); } catch (Exception e) { log.error(" MultipartFileDto 文件转换失败!", e); } finally { //删除临时文件 tempFile.delete(); } }
4. 若依多Sheet页excel内部生成用于上传,而不是直接下载返回
搜索若依多Sheet页 会找到相关代码 关键方法改造exportExcelManySheet 也是临时文件的方法,记得删除
/** * 对list数据源将其里面的数据导入到excel表单 * * @param list 导出数据集合 * @return 结果 * @throws IOException */ public File exportExcelManySheet( List<ExcelExp> list) { File tempFile = null; FileOutputStream out = null; try { String filename = IdUtils.fastSimpleUUID(); //创建临时文件 tempFile = File.createTempFile(filename, ".xlsx"); out = new FileOutputStream(tempFile); createWorkbook(); for (int index = 0; index < list.size(); index++) { this.clazz = list.get(index).getClazz(); this.init(list.get(index).getDataset(), list.get(index).getFileName(), Type.EXPORT); // 取出一共有多少个sheet. // double sheetNo = Math.ceil(list.size() / sheetSize); createSheetManySheet(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(); } } wb.write(out); // return tempFile; } catch (IOException e) { log.error("导出Excel异常{}", e.getMessage()); } finally { IOUtils.closeQuietly(wb); IOUtils.closeQuietly(out); } return tempFile; }