poi_tl处理多张图片的自适应显示
一个字段下多张图片的按比例缩放显示
使用过poi_tl模板引擎的童鞋都知道,单张图片用{{@var}}标签即可实现,下面是多张图片的实现方式以及图片如何在单元格内实现按比例缩放显示。
实现代码
Map<String,Object> dynamicTableMap = new HashMap<>();
//图片数据
List<String> screenShots = param.getJSONArray("images").toJavaList(String.class);
//单元格的最大宽度
Integer maxWidth = 620;
//单元格最大高度
Integer maxHeight = 300;
Integer rowSize = 3; // 每行放3张图片
List<PictureRenderData> pictures = new ArrayList<>();
List<String> resizeList = new ArrayList<>();
//放3张图片的宽高比 默认
double defaultWidthByHeight = (maxWidth / rowSize) * 1.0 / maxHeight;
double singleWidth = maxWidth * 1.0 / rowSize; //一行放3个,单个宽度
double fixWidth = maxWidth * 1.0 / 2; //如果只有一张,且按照宽度调整的,图片就用这个宽度,可按实际情况调整
//要调整宽度或高度的图片数量
Integer resizePic = screenShots.size() % rowSize;
for (int i = 0;i<screenShots.size();i++){
File picture = new File(screenShots.get(i));
BufferedImage sourceImg = ImageIO.read(picture);
double imageWidthByHeight = sourceImg.getWidth() * 1.0 / sourceImg.getHeight();
//这个是要调整的图片
if(screenShots.size() - i <= resizePic){
//动态的宽高比
double dynamicWidthByHeight = (maxWidth / resizePic) * 1.0 / maxHeight;
if(imageWidthByHeight - dynamicWidthByHeight >0 ){
pictures.add(new PictureRenderData((int)fixWidth,(int)((sourceImg.getHeight()*fixWidth)/sourceImg.getWidth()),screenShots.get(i)));
}else if(imageWidthByHeight - dynamicWidthByHeight <0) {
pictures.add(new PictureRenderData(((sourceImg.getWidth()*maxHeight)/sourceImg.getHeight()),maxHeight,screenShots.get(i)));
}
}
else{
if (imageWidthByHeight - defaultWidthByHeight > 0) {
pictures.add(new PictureRenderData((int) singleWidth, (int) ((sourceImg.getHeight() * singleWidth) / sourceImg.getWidth()), screenShots.get(i)));
} else if (imageWidthByHeight - defaultWidthByHeight < 0) {
pictures.add(new PictureRenderData(((sourceImg.getWidth() * maxHeight) / sourceImg.getHeight()), maxHeight, screenShots.get(i)));
}
}
}
dynamicTableMap.put("images",pictures);
Configure config = Configure.builder()
.bind("images",new MultiImageRenderPolicy())
.useSpringEL(false).build();
XWPFTemplate template = XWPFTemplate.compile(resource, config).render(dynamicTableMap);
template.writeToFile("d:/out_example_payment.docx");
//重写策略
public class MultiImageRenderPolicy extends AbstractRenderPolicy<List<PictureRenderData>>{
@Override
public void doRender(RenderContext<List<PictureRenderData>> renderContext) throws Exception {
WhereDelegate whereDelegate = renderContext.getWhereDelegate();
Object obj = renderContext.getThing();
if(obj instanceof List){
List<PictureRenderData> pictureRenderDataList = renderContext.getThing();
if(pictureRenderDataList != null && pictureRenderDataList.size() !=0){
for(PictureRenderData pic : pictureRenderDataList){
InputStream stream = null;;
try{
stream = new ByteArrayInputStream(pic.getPictureSupplier().get());
whereDelegate.addPicture(stream,pic.getPictureType().type(),pic.getPictureStyle().getWidth(),pic.getPictureStyle().getHeight());
}finally {
IOUtils.closeQuietly(stream);
}
}
}
}
}
@Override
protected void afterRender(RenderContext<List<PictureRenderData>> context) {
// 清空标签
clearPlaceholder(context, true);
}
}
模板绑定格式
实现效果
总结说明
- 每行显示几张图片用户可以自己定义,设置rowSize即可
- 当图片数量大于rowSize时,会对多出来的图片重新计算图片宽度
- 文中的宽度高度值都是像素值