2024-04-06 16:28:52 311 0
ezadmin能够根据sql等配置导出对应的数据库数据,默认使用csv,支持自定义的poi导出,在一些业务场景中,列表是有展示图片的,比如产品列表,此时如果需要导出图片就会显得比较麻烦,且这种场景虽不常见,但由于图片大小不固定,且poi默认是使用类似于绝对定位来写入图片的,这样就需要消耗不少时间来调试图片的导出,因此考虑提取公因式。
默认方法如下:
package top.ezadmin;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public class ExcelImageExample {
public static void main(String[] args) throws IOException {
Path ex = Paths.get("/Users/hp/Desktop/workspace/github/ezadmin/ezadmin-web/src/main/resources/工作簿1.xlsx");
Path img = Paths.get("/Users/hp/Desktop/workspace/github/ezadmin/ezadmin-web/src/main/java/top/ezadmin/main.jpg");
XSSFWorkbook workbook= new XSSFWorkbook(Files.newInputStream(ex));
// 读取图片文件到字节数组中
byte[] bytes =Files.readAllBytes(img);
// 将图片作为一个静态单元格放置
ClientAnchor anchor = workbook.getCreationHelper().createClientAnchor();
anchor.setCol1(0); // 图片的起始列
anchor.setRow1(0); // 图片的起始行
// 在单元格中插入图片
Drawing drawing = workbook.getSheetAt(0).createDrawingPatriarch();
int pictureIdx = workbook.addPicture(bytes, Workbook.PICTURE_TYPE_JPEG);
Picture picture = drawing.createPicture(anchor, pictureIdx);
// 调整图片的大小
picture.resize();
// 写入Excel文件
FileOutputStream outputStream = new FileOutputStream("/Users/hp/Desktop/workspace/github/ezadmin/ezadmin-web/src/main/java/top/ezadmin/"+System.currentTimeMillis()+".xlsx");
workbook.write(outputStream);
workbook.close();
outputStream.close();
}
}
此时有一个问题,图片并不是嵌入在excel里面的,而是根据图片自身的大小,100%悬浮展示的。
改造代码:
// 调整图片的大小
picture.resize( 1,1);
此时又有拉伸问题。
于是:
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
BufferedImage image = ImageIO.read(bais);
double cellWidth =
sheet.getColumnWidthInPixels(sheet.getRow(0).getCell(1).getColumnIndex());
double cellHeight = sheet.getRow(0).getHeightInPoints(); // 获取单元格的高度
double cw = cellWidth;
double ch = Units.pointsToPixel((int) cellHeight);
double w = image.getWidth();
double h = image.getHeight();
if (w > h) {//宽大于高,把宽置为1,高等比
picture.resize(1, (h / w) );
} else {
picture.resize(w / h, 1);
}
如果要支持自适应单元格大小。
if (w >= cw && h >= ch) {
double scaleX = (double) cw / w;
double scaleY = (double) ch / h;
System.out.println(scaleX + "\t" + scaleY);
if (w > h) {
picture.resize(1, (h / ch) / (w / cw));
} else {
picture.resize((w / cw) / (h / ch), 1);
}
}
if (w < cw && h < ch) {
double scaleX = (double) w / cw;
double scaleY = (double) h / ch;
System.out.println(scaleX + "\t" + scaleY);
picture.resize(scaleX, scaleY);
}
if (w >= cw && h <= ch) {
double scaleX = (double) w / cw;
double scaleY = (double) h / ch;
System.out.println(scaleX + "\t" + scaleY);
if (w > h) {
picture.resize(1, (h / ch) / (w / cw));
} else {
picture.resize((w / cw) / (h / ch), 1);
}
}
if (w <= cw && h >= ch) {
double scaleX = (double) w / cw;
double scaleY = (double) h / ch;
System.out.println(scaleX + "\t" + scaleY);
if (w > h) {
picture.resize(1, scaleY / scaleX);
} else {
picture.resize(scaleX / scaleY, 1);
}
}