Poi-tl实现图片自定义宽高、固定高度宽度自适应、固定宽度高度自适应
一、编写自定义插件CustomPictureRenderPolicy
CustomPictureRenderPolicy.java
package com.****;
public class CustomPictureRenderPolicy extends PictureRenderPolicy {
private static ToRenderDataConverter<Object, PictureRenderData> converter = new ObjectToPictureRenderDataConverter();
public CustomPictureRenderPolicy() {
}
public PictureRenderData cast(Object source) throws Exception {
return (PictureRenderData)converter.convert(source);
}
protected boolean validate(PictureRenderData data) {
return null != data;
}
protected void afterRender(RenderContext<PictureRenderData> context) {
this.clearPlaceholder(context, false);
}
protected void reThrowException(RenderContext<PictureRenderData> context, Exception e) {
this.logger.info("Render picture " + context.getEleTemplate() + " error: {}", e.getMessage());
String alt = ((PictureRenderData)context.getData()).getAltMeta();
context.getRun().setText(alt, 0);
}
public void beforeRender(RenderContext<PictureRenderData> context) {
//System.out.println("================");
XWPFRun run = context.getRun();
String source = context.getEleTemplate().getSource();
String tagName = context.getEleTemplate().getTagName();
//System.out.println(source);
Pattern pattern = Pattern.compile( "(.*)\\{\\{%"+tagName+"}}(.*)");
XWPFParagraph parent = (XWPFParagraph) run.getParent();
IBody body = parent.getBody();
for (XWPFParagraph paragraph : body.getParagraphs()) {
String text = paragraph.getText();
//System.out.println(text + "-------------------------------");
if (text.contains(source) && ReUtil.isMatch(pattern,text) ) {
PictureStyle pictureStyle = new PictureStyle();
// 读取图片宽高,固定高度,宽度等比例缩放
byte[] bytes = context.getData().readPictureData();
BufferedImage image = null;
try {
// 将图片字节数据转换为 BufferedImage
InputStream inputStream = new ByteArrayInputStream(bytes);
image = ImageIO.read(inputStream);
// 获取图片的宽高
int originalWidth = image.getWidth();
int originalHeight = image.getHeight();
// 固定高度,例如设置为 200 像素
int fixedHeight = 150;
// 按比例计算新的宽度
int scaledWidth = (int) ((double) originalWidth / originalHeight * fixedHeight);
//System.out.println("原始宽度: " + originalWidth + ", 原始高度: " + originalHeight);
//System.out.println("新宽度: " + scaledWidth + ", 固定高度: " + fixedHeight);
pictureStyle.setWidth(scaledWidth);
pictureStyle.setHeight(fixedHeight);
// scaledBytes 可以用于后续处理,例如存储或传输
} catch (IOException e) {
e.printStackTrace();
}
context.getData().setPictureStyle(pictureStyle);
}
}
}
public void doRender(RenderContext<PictureRenderData> context) throws Exception {
CustomPictureRenderPolicy.Helper.renderPicture(context.getRun(), (PictureRenderData) context.getData());
}
public static class Helper {
public Helper() {
}
public static void renderPicture(XWPFRun run, PictureRenderData picture) throws Exception {
byte[] imageBytes = picture.readPictureData();
if (null == imageBytes) {
throw new IllegalStateException("Can't read picture byte arrays!");
} else {
// 根据图片流 设置图片类型
PictureType pictureType = picture.getPictureType();
if (null == pictureType) {
pictureType = PictureType.suggestFileType(imageBytes);
}
// 图片类型为空,报错
if (null == pictureType) {
throw new RenderException("PictureRenderData must set picture type!");
} else {
PictureStyle style = picture.getPictureStyle();
if (null == style) {
style = new PictureStyle();
}
int width = style.getWidth();
int height = style.getHeight();
if (pictureType == PictureType.SVG) {
imageBytes = SVGConvertor.toPng(imageBytes, (float) width, (float) height,1);
pictureType = PictureType.PNG;
}
if (!isSetSize(style)) {
BufferedImage original = BufferedImageUtils.readBufferedImage(imageBytes);
width = original.getWidth();
height = original.getHeight();
if (style.getScalePattern() == WidthScalePattern.FIT) {
BodyContainer bodyContainer = BodyContainerFactory.getBodyContainer(run);
int pageWidth = UnitUtils.twips2Pixel(bodyContainer.elementPageWidth((IBodyElement) run.getParent()));
if (width > pageWidth) {
double ratio = (double) pageWidth / (double) width;
width = pageWidth;
height = (int) ((double) height * ratio);
}
}
}
InputStream stream = new ByteArrayInputStream(imageBytes);
try {
PictureStyle.PictureAlign align = style.getAlign();
if (null != align && run.getParent() instanceof XWPFParagraph) {
((XWPFParagraph) run.getParent()).setAlignment(ParagraphAlignment.valueOf(align.ordinal() + 1));
}
run.addPicture(stream, pictureType.type(), "Generated", Units.pixelToEMU(width), Units.pixelToEMU(height));
} catch (Throwable var13) {
try {
stream.close();
} catch (Throwable var12) {
var13.addSuppressed(var12);
}
throw var13;
}
stream.close();
}
}
}
private static boolean isSetSize(PictureStyle style) {
return (style.getWidth() != 0 || style.getHeight() != 0) && style.getScalePattern() == WidthScalePattern.NONE;
}
}
}
二、word中标签
{{%imgUrl}}
三、调用
ConfigureBuilder builder = Configure.builder();
//图片的标签%
builder.addPlugin('%', new CustomPictureRenderPolicy());