使用poi导入图片并生成富文本

使用poi导入图片并生成富文本

用poi做试题导入时,部分试题题干或者答案选项有图片的存在,所以需要获取题干或答案选项对应单元格的图片后存库,然后拼接成富文本用于前端展示。由于excel插入的图片是悬浮在上层的,这里我们获取图片左上角对应的角标作为单元格的角标,所以,导入时图片尽可能放在对应的单元格。

package soohoo;


import cn.hutool.core.io.FileUtil;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.*;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

import static org.apache.poi.ss.usermodel.CellType.*;

/**
 * @author yangyi
 * @description
 * @date 2020/8/21
 */
public class ImportPictureTest {

    private final static String EXCEL_XLSX = "xlsx";
    private final static String EXCEL_XLS = "xls";


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

        String filePath = "C:\\Users\\123\\Desktop\\图片导入测试.xlsx";
//        String filePath = "C:\\Users\\123\\Desktop\\图片导入测试.xls";

        Workbook wb = getWorkbook(filePath);
        if (wb == null) {
            throw new Exception("excel为空!");
        }
//        Sheet sheet = wb.getSheetAt(0);
        Sheet sheet = wb.getSheetAt(1);
        StringBuilder html = new StringBuilder();
        FileOutputStream os = null;
        Map<String, PictureData> pictureDataMap = listSheetPictureData(sheet);
        int lastRowNum = sheet.getLastRowNum();
        for (int i = 0; i <= lastRowNum; i++) {
            Row row = sheet.getRow(i);
            short lastCellNum = row.getLastCellNum();
            for (int j = 0; j < lastCellNum; j++) {
                Cell cell = row.getCell(j);
                if (cell == null) {
                    continue;
                }
                cell.setCellType(STRING);
                String text = cell.getStringCellValue();
                html.append(text);
                PictureData pictureData = pictureDataMap.get(i + "_" + j);
                if (pictureData != null) {
                    StringBuilder pictureName = new StringBuilder("C:\\Users\\123\\Desktop\\");
                    pictureName.append(System.currentTimeMillis())
                            .append("_")
                            .append(i)
                            .append("_")
                            .append(j)
                            .append(".")
                            .append(pictureData.suggestFileExtension());
                    os = new FileOutputStream(pictureName.toString());
                    os.write(pictureData.getData());
                    os.flush();
                    os.close();
                    html.append("<img src=").append("'").append(pictureName.toString()).append("' />");
                }
                html.append("<br>");
            }
        }
        String path = "C:\\Users\\123\\Desktop\\test.html";
        os = new FileOutputStream(path);
        byte[] bytes = html.toString().getBytes(StandardCharsets.UTF_8);
        os.write(bytes);
        os.flush();
        os.close();
    }


    /**
     * 获取sheet中图片的信息
     *
     * @param sheet sheet
     * @return map;key:单元格横坐标纵坐标(图片左上角所在单元格的角标),value:图片信息
     */
    private static Map<String, PictureData> listSheetPictureData(Sheet sheet) {
        Map<String, PictureData> map = new HashMap<>(16);
        Drawing<?> drawingPatriarch = sheet.getDrawingPatriarch();
        for (Shape shape : drawingPatriarch) {
           if (shape instanceof Picture) {
                Picture pic = (Picture) shape;
                PictureData pictureData = pic.getPictureData();
                ClientAnchor anchor = pic.getClientAnchor();
                if (pictureData != null && anchor != null) {
                    map.put(anchor.getRow1() + "_" + anchor.getCol1(), pictureData);
                }
            }
        }
        return map;
    }

    /**
     * 获取excel的workbook
     *
     * @param filePath excel文件路径
     * @return workbook
     * @throws IOException IOException
     */
    private static Workbook getWorkbook(String filePath) throws IOException {
        Workbook wb = null;
        String suffix = FileUtil.getSuffix(filePath);
        if (EXCEL_XLS.equals(suffix)) {
            wb = new HSSFWorkbook(new FileInputStream(filePath));
        }
        if (EXCEL_XLSX.equals(suffix)) {
            wb = new XSSFWorkbook(new FileInputStream(filePath));
        }
        return wb;
    }
}

在实际的试题中,可能存在图片在一段文本的中间,像这样:

在这里插入图片描述
想要的富文本应该是这样:

图片<img src="" />描述一个什么情况?

但是poi只能拿到图片所在单元格角标,没法知道图片在文本的哪个位置,得到的富文本将会是这样:

图片描述一个什么情况?<img src="" />

最后的前端展示的效果是:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值