动态生成excel文档信息,里面的图片是动态的

需求就是,有人提供了一个excel模板,模板里面的文字和图片都是从数据库或者文件服务器获取的,所有图片是动态的,图片获取也是多张的,需要填充到excel里面,最终返回给前端,所以我就想用freemaker + poi的技术,freemaker做文字填充相对简单点,图片填充就用poi的接口,我到网上找了个现成的demo但是样式全变了,
https://www.cnblogs.com/Hlingoes/p/14828344.html
https://github.com/Hlingoes/freemaker-poi-excel (仓库地址),我按照仓库的demo试里面的是没问题的,但是试我自己的,我的样式就全乱了
如下图

img

因为poi的api的合并单元格,样式填充我用的不是很熟练,我只有freemaker的api,所以看看有没有现成的解决方案

需求模板图

img

有点被你误导了__
你到底是要打印功能还是导出excel功能?
首先分为2块。
第一:你要的是打印功能
第二:数据图片动态加载
那么就一个一个来。
1.可以参考这个来实现打印:https://blog.csdn.net/yxh13521338301/article/details/85235442
2.你的数据可以动态从数据库取,然后渲染到页面,其中第一步链接里也有。

chatgpt:
要在Java中使用Freemarker动态生成Excel文档,可以使用POI和JExcelAPI这两个Java库中的一个来操作Excel。建议使用POI,因为它更强大和灵活。

以下是使用POI和Freemarker动态生成Excel文档并包含图片的示例代码:

首先,导入POI和Freemarker库的依赖项。
创建一个Excel模板文件,其中包含Excel的格式和样式,以及包含要动态插入的图片的占位符。
在Java代码中,读取Excel模板文件并将其解析为Freemarker模板。
创建一个数据模型,其中包含要在Excel中动态生成的数据和图片。
使用Freemarker模板将数据模型应用于模板文件,并将结果写入Excel文件。
以下是示例代码:

// 导入依赖项
import java.io.*;
import java.util.*;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.xssf.usermodel.*;
import freemarker.template.*;

public class ExcelGenerator {

    public static void main(String[] args) throws Exception {

        // 读取Excel模板文件
        FileInputStream fis = new FileInputStream("template.xls");
        Workbook workbook = new HSSFWorkbook(fis);

        // 创建Freemarker模板
        Configuration cfg = new Configuration(Configuration.VERSION_2_3_23);
        cfg.setClassForTemplateLoading(ExcelGenerator.class, "/");
        Template template = cfg.getTemplate("template.ftl");

        // 创建数据模型
        Map<String, Object> data = new HashMap<String, Object>();
        data.put("name", "John Doe");
        List<String> images = new ArrayList<String>();
        images.add("image1.jpg");
        images.add("image2.jpg");
        images.add("image3.jpg");
        data.put("images", images);

        // 将数据应用于模板并将结果写入Excel文件
        StringWriter sw = new StringWriter();
        template.process(data, sw);
        String output = sw.toString();
        Sheet sheet = workbook.getSheetAt(0);
        int rownum = 1;
        for (String image : images) {
            InputStream is = new FileInputStream(image);
            byte[] bytes = IOUtils.toByteArray(is);
            int pictureIndex = workbook.addPicture(bytes, Workbook.PICTURE_TYPE_JPEG);
            Drawing drawing = sheet.createDrawingPatriarch();
            CreationHelper helper = workbook.getCreationHelper();
            ClientAnchor anchor = helper.createClientAnchor();
            anchor.setCol1(1);
            anchor.setRow1(rownum);
            anchor.setCol2(2);
            anchor.setRow2(rownum + 2);
            Picture pict = drawing.createPicture(anchor, pictureIndex);
            rownum += 3;
        }
        FileOutputStream fos = new FileOutputStream("output.xls");
        workbook.write(fos);
        fos.close();

    }

}


在上面的代码中,template.xls是Excel模板文件,其中包含Excel的格式和样式,以及包含要动态插入的图片的占位符。template.ftl是Freemarker模板,用于将数据模型应用于Excel模板文件并生成最终的Excel文件。

data是数据模型,其中包含要在Excel中动态生成的数据和图片。在这个例子中,数据模型包含一个名为name的字符串变量和一个名为images的字符串列表,其中包含要动态插入的图片的文件名。

在将数据模型应用于Freemarker模板后,将其写入Excel文件。对于每个要插入的图片,将其作为字节数组读取,将其添加到Excel工作簿中,并使用Drawing和ClientAnchor将其插入到Excel单元格中。

最后,将Excel工作簿写入输出流,并将其保存到名为output.xls的文件中。

请注意,这只是一个简单的示例,您可能需要根据自己的需求进行修改。特别是,您需要注意图片的大小和位置,以便它们不会覆盖其他单元格中的数据。

题主你的问题有点模糊,可以再详细描述下。

图片的样式是动态多张的

这句话的意思该怎么理解。我的理解是后端有多个不确定的图片,需要代码动态选取某一张,将图片渲染到excel中。 这样理解对吗?

动态打印

“动态打印” 这句话应该是渲染的意思吧? 使用ftl将图片渲染,然后生成excel吧。 可以将代码发出来,这边看下什么问题。

关于excel生成的可以参考:关于Java使用EasyExcel导出动态数据为Excel文件示例

结果示例可以参考:https://img-blog.csdnimg.cn/1cc86ee5dffa48669e2b97283585fad2.png

该回答引用ChatGPT
您好,我认为可以通过在Freemarker中使用Java代码,动态地生成包含图片的HTML代码,并将其输出到浏览器中实现动态打印的功能。

在Freemarker中,您可以通过以下方式表示图片:

<img src="path/to/image.jpg" alt="image description">

要动态地生成多张图片的HTML代码,您可以使用Freemarker的循环结构,在模板中循环遍历多个图片,并生成相应的HTML代码。例如,以下代码将生成三个不同的图片:

<#list images as image>
    <img src="${image.path}" alt="${image.description}">
</#list>

在Java代码中,您可以通过将图片的URL或字节数组传递给模板来生成包含图片的HTML代码。例如,以下Java代码使用Spring MVC将包含多个图片的HTML代码发送到浏览器:

@GetMapping("/print")
public void print(Model model, HttpServletResponse response) throws IOException {
    List<Image> images = getImages(); // 获取图片列表
    model.addAttribute("images", images); // 将图片列表添加到模型中

    // 渲染模板并将结果发送到浏览器
    response.setContentType("text/html");
    Template template = configuration.getTemplate("print.ftl");
    Writer writer = response.getWriter();
    template.process(model.asMap(), writer);
    writer.flush();
}

在上面的代码中,getImages()方法将返回一个包含多个图片的列表。然后,将这些图片添加到Freemarker模型中。最后,使用configuration.getTemplate()方法获取名为print.ftl的模板文件,并使用template.process()方法将模型和输出流作为参数渲染模板。在这个过程中,Freemarker将使用循环结构生成多个HTML代码块,每个代码块包含一个图片。

请注意,为了使此代码正常工作,必须在Spring配置中包含以下代码:

@Bean
public FreeMarkerConfigurer freeMarkerConfigurer() {
    FreeMarkerConfigurer configurer = new FreeMarkerConfigurer();
    configurer.setTemplateLoaderPath("/WEB-INF/templates/");
    return configurer;
}

上面的代码将Freemarker的模板加载路径设置为/WEB-INF/templates/。这意味着模板文件必须放置在/WEB-INF/templates/目录下,以便正确加载模板。

以下答案由GPT-3.5大模型与博主波罗歌共同编写:
实现动态生成 Excel 文档并包含图片的方式有很多种,其中使用 Apache POI 结合 FreeMarker 是一种比较简单易懂的方式。

具体实现步骤如下:

  1. 添加依赖

在 Maven 项目中,需要在 pom.xml 文件中添加以下依赖:

<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>4.1.2</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>4.1.2</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml-schemas</artifactId>
    <version>4.1.2</version>
</dependency>
<dependency>
    <groupId>org.apache.xmlbeans</groupId>
    <artifactId>xmlbeans</artifactId>
    <version>3.1.0</version>
</dependency>
<dependency>
    <groupId>org.freemarker</groupId>
    <artifactId>freemarker</artifactId>
    <version>2.3.28</version>
</dependency>
  1. 编写模板

在 FreeMarker 中定义一个包含图片的模板文件,例如:

```xml

<worksheet xmlns="http://s/

基于最新版ChatGPT4的回答,望采纳!!!有其他问题也可以询问我哦💕(最新版更智能,功能更加强大):
根据您提供的信息,我可以推荐两种解决方案:

直接使用POI API填充文本和图片
您可以使用POI API直接填充文本和图片,而无需使用FreeMarker。以下是一个示例代码,演示如何使用POI API来处理您的Excel模板:

import java.io.*;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.*;
import org.apache.poi.ss.util.*;
import org.apache.poi.util.IOUtils;

public class ExcelTemplate {
    public static void main(String[] args) throws Exception {
        String templatePath = "template.xlsx"; // 模板文件路径
        String outputPath = "output.xlsx"; // 输出文件路径

        // 从模板文件创建工作簿对象
        FileInputStream input = new FileInputStream(new File(templatePath));
        XSSFWorkbook workbook = new XSSFWorkbook(input);
        input.close();

        // 获取第一个工作表
        XSSFSheet sheet = workbook.getSheetAt(0);

        // 填充文本数据
        fillText(sheet, "A2", "John Doe");
        fillText(sheet, "B2", "123 Main St.");
        fillText(sheet, "C2", "jdoe@example.com");

        // 填充图片数据
        InputStream imageStream = new FileInputStream(new File("image.jpg"));
        byte[] imageData = IOUtils.toByteArray(imageStream);
        int pictureIndex = workbook.addPicture(imageData, Workbook.PICTURE_TYPE_JPEG);
        imageStream.close();
        CreationHelper helper = workbook.getCreationHelper();
        Drawing<?> drawing = sheet.createDrawingPatriarch();
        ClientAnchor anchor = helper.createClientAnchor();
        anchor.setCol1(CellReference.convertColStringToIndex("D"));
        anchor.setRow1(1);
        Picture picture = drawing.createPicture(anchor, pictureIndex);
        picture.resize();

        // 合并单元格并设置样式
        CellStyle style = workbook.createCellStyle();
        BorderStyle borderStyle = BorderStyle.THIN;
        short borderColor = IndexedColors.BLACK.getIndex();
        style.setBorderTop(borderStyle);
        style.setBorderRight(borderStyle);
        style.setBorderBottom(borderStyle);
        style.setBorderLeft(borderStyle);
        style.setTopBorderColor(borderColor);
        style.setRightBorderColor(borderColor);
        style.setBottomBorderColor(borderColor);
        style.setLeftBorderColor(borderColor);
        style.setAlignment(HorizontalAlignment.CENTER);
        style.setVerticalAlignment(VerticalAlignment.CENTER);
        Font font = workbook.createFont();
        font.setFontName("Arial");
        font.setFontHeightInPoints((short)12);
        font.setBold(true);
        style.setFont(font);
        sheet.addMergedRegion(CellRangeAddress.valueOf("A4:D4"));
        XSSFCell cell = sheet.getRow(3).getCell(0);
        cell.setCellValue("This is a merged cell");
        cell.setCellStyle(style);

        // 保存工作簿到输出文件
        FileOutputStream output = new FileOutputStream(new File(outputPath));
        workbook.write(output);
        output.close();
    }

    // 辅助方法,填充文本数据到指定单元格
    private static void fillText(XSSFSheet sheet, String cellRef, String text) {
        XSSFCell cell = sheet.getRow(CellReference.getCellRef(cellRef).getRow()).getCell(CellReference.getCellRef(cellRef).getCol());
        cell.setCellValue(text);
    }
}

在上述代码中,我们首先从模板文件创建一个XSSFWorkbook对象,然后获取要填充的工作表。接下来,我们使用fillText()方法填充文本数据,并使用POI API将图片插入到单元格中。最后,我们合并单元格并设置单元格样式,然后将工作簿保存到输出文件。

使用FreeMarker和POI API混合解决方案
您可以使用FreeMarker和POI API结合处理Excel模板。以下是一个示例代码,演示如何使用FreeMarker和POI API来处理您的Excel模板:

import java.io.*;
import java.util.*;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.*;
import freemarker.template.*;

public class ExcelTemplate {
    public static void main(String[] args) throws Exception {
        String templatePath = "template.xlsx"; // 模板文件路径
        String outputPath = "output.xlsx"; // 输出文件路径

        // 从模板文件创建工作簿对象
        FileInputStream input = new FileInputStream(new File(templatePath));
        XSSFWorkbook workbook = new XSSFWorkbook(input.close();

    // 获取第一个工作表
    XSSFSheet sheet = workbook.getSheetAt(0);

    // 使用FreeMarker填充文本数据
    Map<String, Object> dataModel = new HashMap<>();
    dataModel.put("name", "John Doe");
    dataModel.put("address", "123 Main St.");
    dataModel.put("email", "jdoe@example.com");
    String textTemplate = "${name}\n${address}\n${email}";
    Template template = new Template("textTemplate", new StringReader(textTemplate), new Configuration());
    StringWriter writer = new StringWriter();
    template.process(dataModel, writer);
    fillText(sheet, "A2", writer.toString());

    // 使用POI API插入图片
    InputStream imageStream = new FileInputStream(new File("image.jpg"));
    byte[] imageData = IOUtils.toByteArray(imageStream);
    int pictureIndex = workbook.addPicture(imageData, Workbook.PICTURE_TYPE_JPEG);
    imageStream.close();
    CreationHelper helper = workbook.getCreationHelper();
    Drawing<?> drawing = sheet.createDrawingPatriarch();
    ClientAnchor anchor = helper.createClientAnchor();
    anchor.setCol1(CellReference.convertColStringToIndex("D"));
    anchor.setRow1(1);
    Picture picture = drawing.createPicture(anchor, pictureIndex);
    picture.resize();

    // 使用FreeMarker合并单元格并设置样式
    String styleTemplate = "<#assign style = workbook.createCellStyle()>" +
            "<#assign borderStyle = style.BORDER_THIN>" +
            "<#assign borderColor = style.BLACK>" +
            "<#assign style.borderTop = borderStyle>" +
            "<#assign style.borderRight = borderStyle>" +
            "<#assign style.borderBottom = borderStyle>" +
            "<#assign style.borderLeft = borderStyle>" +
            "<#assign style.topBorderColor = borderColor>" +
            "<#assign style.rightBorderColor = borderColor>" +
            "<#assign style.bottomBorderColor = borderColor>" +
            "<#assign style.leftBorderColor = borderColor>" +
            "<#assign style.alignment = style.ALIGN_CENTER>" +
            "<#assign style.verticalAlignment = style.VERTICAL_CENTER>" +
            "<#assign font = workbook.createFont()>" +
            "<#assign font.fontName = 'Arial'>" +
            "<#assign font.fontHeightInPoints = 12>" +
            "<#assign font.bold = true>" +
            "<#assign style.setFont(font)>" +
            "<#assign sheet.addMergedRegion(workbook.getCreationHelper().createCellRangeAddress(3,3,0,3))>" +
            "<#assign cell = sheet.getRow(3).getCell(0)>" +
            "<#assign cell.setCellValue('This is a merged cell')>" +
            "<#assign cell.setCellStyle(style)>";
    Template styleTemplate = new Template("styleTemplate", new StringReader(styleTemplate), new Configuration());
    writer = new StringWriter();
    styleTemplate.process(Collections.singletonMap("workbook", workbook), writer);

    // 保存工作簿到输出文件
    FileOutputStream output = new FileOutputStream(new File(outputPath));
    workbook.write(output);
    output.close();
}

// 辅助方法,填充文本数据到指定单元格
private static void fillText(XSSFSheet sheet, String cellRef, String text) {
    XSSFCell cell = sheet.getRow(CellReference.getCellRef(cellRef).getRow()).getCell(CellReference.getCellRef(cellRef).getCol());
    cell.setCellValue(text);
}
}

在上述代码中,我们仍然从模板文件创建一个XSSFWorkbook对象,并获取要填充的工作表。然后,我们使用FreeMarker填充文本数据,并使用POI API插入图片。接下来,我们使用FreeMarker生成单元格样式,并将其应用于工作表。最后,我们将工作簿保存到输出文件。

需要注意的是,在使用FreeMarker时,您需要将workbook对象添加到数据模型中,以便在模板中访问它。

该回答引用ChatGPT
根据问题描述,你需要动态生成Excel文档,其中包含动态的图片和文字,图片需要从数据库或文件服务器获取,最终返回给前端。你已经尝试使用freemarker和poi技术实现,但是样式出现了问题。
针对这个问题,我建议你可以尝试以下步骤:
1. 确认Excel模板的样式和格式,包括单元格的合并、字体、颜色、边框等,以便在代码中进行相应的设置。
2. 使用poi的API读取Excel模板,获取模板中的单元格样式和格式,然后将这些样式和格式应用到生成的Excel文档中。
3. 使用freemarker的API将数据填充到Excel文档中,包括文字和图片。对于图片,可以使用poi的API将图片插入到Excel文档中,然后设置图片的位置和大小。
下面是一个简单的示例代码,演示如何使用poi和freemarker生成Excel文档并填充数据:
java
// 读取Excel模板
Workbook workbook = WorkbookFactory.create(new File("template.xlsx"));
Sheet sheet = workbook.getSheetAt(0);
// 获取模板中的样式和格式
CellStyle cellStyle = sheet.getRow(0).getCell(0).getCellStyle();
Font font = workbook.getFontAt(cellStyle.getFontIndex());
// 使用freemarker填充数据
Configuration cfg = new Configuration(Configuration.VERSION_2_3_30);
cfg.setDefaultEncoding("UTF-8");
cfg.setClassForTemplateLoading(this.getClass(), "/templates");
Template template = cfg.getTemplate("template.ftl");
Map data = new HashMap<>();
data.put("name", "张三");
data.put("age", 20);
data.put("image", new File("image.jpg"));
Writer out = new FileWriter(new File("output.xlsx"));
template.process(data, out);
out.close();
// 将图片插入到Excel文档中
Drawing drawing = sheet.createDrawingPatriarch();
ClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, 1, 1, 2, 4);
Picture picture = drawing.createPicture(anchor, workbook.addPicture(IOUtils.toByteArray(new FileInputStream(new File("image.jpg"))), Workbook.PICTURE_TYPE_JPEG)));
picture.resize(1.0, 1.0);

在这个示例代码中,我们首先读取Excel模板,然后获取模板中的样式和格式。接着使用freemarker填充数据,包括文字和图片。最后将图片插入到Excel文档中,并设置图片的位置和大小。
需要注意的是,这只是一个简单的示例代码,实际应用中还需要根据具体需求进行相应的调整和优化。不知道你这个问题是否已经解决, 如果还没有解决的话:

如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^

可以借鉴下
http://www.studyofnet.com/717110295.html

https://blog.csdn.net/leesinbad/category_12207471.html
这里有三篇excel的文章,希望对你有用

使用Freemarker + POI来将数据填充到Excel中,有时确实会出现样式改变的情况,这可能是因为POI处理Excel的方式与Excel本身的处理方式不同,导致部分样式无法被完全还原。通常来说,我们可以尝试以下解决办法:

  1. 检查Excel模板中是否存在合并单元格、复杂的边框或者其他特殊样式。如果是这些元素导致的样式变化,可以考虑调整模板中的样式,使得最终生成的Excel与原始样式更加接近。

  2. 将POI处理生成的Excel和原始Excel进行比对,查看哪些样式出现了变化,并尝试找到合适的方法进行修复。

  3. 对于一些复杂的样式或者需要复杂数据处理逻辑的Excel,可以考虑尝试使用专业的Excel处理库,如Aspose.Cells,其能够更好地处理复杂的样式和数据结构。

  4. 如果您不是特别注重样式的还原,可以尝试不使用Excel模板,直接使用POI将数据填充到新建的Excel中,这样就避免了 Excel 模板转换、样式还原等问题。

该回答引用于GPT与OKX小二共同编写:
  • 该回答引用于GPT与OKX小二共同编写:

如果使用 POI 实现动态填充 Excel 模板,最好的方法是:

  1. 将 Excel 模板分成三个部分:表头、主体和表尾。

  2. 使用 POI 的接口按照以下顺序逐步填充数据内容:

  • 填充表头
  • 填充主体数据
  • 处理插入图片(本质上是插入图片的链接或者流):
    • 如果是网络图片,使用 URL 连接并插入到单元格中;
    • 如果是本地图片,将图片转换为二进制数组(byte[]),创建 Excel 图片并插入到单元格中。
  • 填充表尾
  1. 样式处理:对于表头和表尾,可以通过 POI 接口设置样式,对于主体数据,可以在模板中预置样式。

需要注意的是,如果直接使用 POI 接口添加图片到单元格中,可能会导致样式问题,因为样式也受到一些限制。为了避免这些问题,可以在模板中预留图片的位置,并在填充数据时使用 Freemarker 模板引擎生成图片的 HTML 代码,在 POI 中使用该 HTML 代码创建单元格。这样可以确保图片与其他内容的样式保持一致,即使内容超出单元格大小,也可以通过设置单元格的样式来调整。

另外,需要注意的是,如果要使用 POI 处理合并单元格、单元格样式等复杂表格操作,需要严格按照 POI API 的规范进行操作,确保数据的正确性和稳定性。可以参考官方文档来使用 POI 接口。

chatGTP:根据您提供的需求模板图,您需要在Excel中动态填充文本和图片,并且保留模板的样式。下面是我建议的解决方案:

使用POI来读取模板Excel文件,并将其转换成一个可编辑的工作簿对象。
使用FreeMarker来生成一个数据模型,该数据模型包含需要在Excel中填充的文本和图片数据。
使用POI和FreeMarker来填充Excel单元格中的文本和图片数据。对于文本,可以使用POI的接口将文本内容填充到单元格中。对于图片,可以使用POI的接口将图片插入到单元格中,并根据需要调整单元格的大小和位置。
最后,将编辑后的工作簿对象写入新的Excel文件中,并返回给前端。
下面是一个简单的示例代码,演示了如何使用POI和FreeMarker来动态填充Excel模板:

import java.io.*;
import java.util.*;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.*;
import freemarker.template.*;

public class ExcelGenerator {
    public static void main(String[] args) {
        try {
            // 读取Excel模板文件
            InputStream inputStream = new FileInputStream("template.xlsx");
            Workbook workbook = new XSSFWorkbook(inputStream);
            Sheet sheet = workbook.getSheetAt(0);

            // 准备数据模型
            Map<String, Object> dataModel = new HashMap<>();
            dataModel.put("title", "动态生成Excel");
            dataModel.put("subtitle", "使用POI和FreeMarker");
            dataModel.put("date", new Date());
            dataModel.put("image1", new FileInputStream("image1.jpg"));
            dataModel.put("image2", new FileInputStream("image2.jpg"));

            // 准备FreeMarker配置
            Configuration freemarkerCfg = new Configuration(Configuration.VERSION_2_3_30);
            freemarkerCfg.setClassForTemplateLoading(ExcelGenerator.class, "/");
            freemarkerCfg.setDefaultEncoding("UTF-8");

            // 获取FreeMarker模板
            Template template = freemarkerCfg.getTemplate("template.ftl");

            // 使用FreeMarker填充Excel单元格
            StringWriter stringWriter = new StringWriter();
            template.process(dataModel, stringWriter);
            String outputText = stringWriter.toString();
            System.out.println(outputText); // 调试用,可以查看生成的XML内容

            // 将生成的XML内容写入Excel单元格
            sheet.createRow(2).createCell(0).setCellValue(outputText);

            // 插入图片
            Row row = sheet.createRow(4);
            byte[] imageBytes1 = IOUtils.toByteArray(new FileInputStream("image1.jpg"));
            byte[] imageBytes2 = IOUtils.toByteArray(new FileInputStream("image2.jpg"));
            int pictureIdx1 = workbook.addPicture(imageBytes1, Workbook.PICTURE_TYPE_JPEG);
            int pictureIdx2 = workbook.addPicture(imageBytes2, Workbook.PICTURE_TYPE_JPEG);
            Drawing drawing = row.createCell(0).getSheet().createDrawingPatriarch();
            ClientAnchor anchor1 = drawing.createAnchor(0, 0, 0, 0, 0, 4, 5, 7);
            ClientAnchor anchor2 = drawing.createAnchor(0, 0, 0 , 0, 8, 9);
        drawing.createPicture(anchor1, pictureIdx1);
        drawing.createPicture(anchor2, pictureIdx2);

        // 将编辑后的工作簿对象写入新的Excel文件中
        FileOutputStream fileOut = new FileOutputStream("output.xlsx");
        workbook.write(fileOut);
        fileOut.close();

        // 清理资源
        workbook.close();
        inputStream.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
}



上述代码中,我们首先使用POI来读取Excel模板文件,并获取工作簿和工作表对象。接下来,我们使用FreeMarker生成一个数据模型,包含需要在Excel中填充的文本和图片数据。然后,我们使用FreeMarker填充Excel单元格,并将生成的XML内容写入工作表中。最后,我们使用POI插入图片,并将编辑后的工作簿对象写入新的Excel文件中。

需要注意的是,在插入图片时,我们使用了POI的Drawing对象来创建图片锚点,然后将锚点与图片一起插入到单元格中。锚点的位置可以使用ClientAnchor对象进行调整。

希望这个示例代码能够帮助你解决Excel模板填充中的问题。如果您有任何疑问,请随时在这里提出。