java - 在 Apache POI 3.9 中使用 autosizeColumn 出现在同一列上的图像被拉伸(stretch)

标签 java excel apache-poi

我在 Excel 工作表中有一张图片和图片下方的一些文本。当我将 autoSizeColumn() 应用于显示文本的列时,图像也会被拉伸(stretch)。 我还将 anchortype 设置为 2,但这并不能保护图像以调整大小。 我在这里发布了一些示例代码。

public static void main(String[] args) {
    try{
    XSSFWorkbook book = new XSSFWorkbook();
    XSSFSheet sheet = book.createSheet("Test Sheet");
     InputStream is = new          FileInputStream("D:\\RPM_Eclipse_Workspaces\\B6.9\\00POI\\Chrysanthemum.jpg");
        byte[] bytes = IOUtils.toByteArray(is);
        int pictureIdx = book.addPicture(bytes, Workbook.PICTURE_TYPE_PNG);
        Drawing drawing = sheet.createDrawingPatriarch();
        ClientAnchor anchor = new XSSFClientAnchor(0, 0, 1023, 255, 2,2,10,10);

        //Image should not get Resized while doing Autosize
        anchor.setAnchorType(ClientAnchor.DONT_MOVE_AND_RESIZE);
        Picture pict = drawing.createPicture(anchor, pictureIdx);

        XSSFRow row = sheet.createRow(12);
        for(int i = 2 ; i < 11 ; i++){
            XSSFCell cell = row.createCell(i);
            cell.setCellValue("oval (although anchor's type is set to MOVE_DONT_RESIZE ). ... But the one way to ");

        }
       sheet.autoSizeColumn(2);
    book.write(new FileOutputStream(new File("D:\\auto.xlsx")));
    System.out.println("=== DONE ===");
    }catch (Exception e){

    }
}

最佳答案

兴趣点使用TwoCellAnchors用于添加图片...所以有点讨厌的反射,您可以添加带有 OneCellAnchor 的图片

在示例中,drawing.createAnchor(10, 10, 110, 110, 2, 2, 0, 0) 用于将图像放置在距单元格左上角 10x10 的位置( 2,2) 并将图片缩放到 100x100 像素,即 110-10。

(使用 Libre Office 4.0、Excel Viewer 2010 测试)

import java.io.*;
import java.lang.reflect.*;

import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.util.IOUtils;
import org.apache.poi.xssf.usermodel.*;
import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D;
import org.openxmlformats.schemas.drawingml.x2006.spreadsheetDrawing.*;

public class Automation {

    public static void main(String[] args) throws Exception {
        XSSFWorkbook book = new XSSFWorkbook();
        XSSFSheet sheet = book.createSheet("Test Sheet");
        InputStream is = new FileInputStream("src/test/resources/smiley.jpg");
        byte[] bytes = IOUtils.toByteArray(is);
        int pictureIdx = book.addPicture(bytes, Workbook.PICTURE_TYPE_PNG);
        XSSFDrawing drawing = sheet.createDrawingPatriarch();

        XSSFClientAnchor anchor = drawing.createAnchor(10, 10, 110, 110, 2, 2, 0, 0);

        createPicture(anchor, pictureIdx, drawing);

        XSSFRow row = sheet.createRow(12);
        for (int i = 2; i < 11; i++) {
            XSSFCell cell = row.createCell(i);
            cell.setCellValue("oval (although anchor's type is set to MOVE_DONT_RESIZE ). ... But the one way to ");

        }
        sheet.autoSizeColumn(2);
        book.write(new FileOutputStream(new File("auto.xlsx")));
    }

    public static XSSFPicture createPicture(XSSFClientAnchor anchor, int pictureIndex, XSSFDrawing drawing)
    throws Exception
    {
        Method m = XSSFDrawing.class.getDeclaredMethod("addPictureReference", int.class);
        m.setAccessible(true);
        PackageRelationship rel = (PackageRelationship)m.invoke(drawing, (Integer)pictureIndex);

        long shapeId = 1000+drawing.getCTDrawing().sizeOfOneCellAnchorArray();
        CTOneCellAnchor ctAnchor = createOneCellAnchor(drawing, anchor);
        CTPicture ctShape = ctAnchor.addNewPic();

        m = XSSFPicture.class.getDeclaredMethod("prototype");
        m.setAccessible(true);
        CTPicture ctp = (CTPicture)m.invoke(null);
        ctShape.set(ctp);
        ctShape.getNvPicPr().getCNvPr().setId(shapeId);

        Constructor<XSSFPicture> picCon = XSSFPicture.class
            .getDeclaredConstructor(XSSFDrawing.class, CTPicture.class);
        picCon.setAccessible(true);

        XSSFPicture shape = picCon.newInstance(drawing, ctShape);
        Field f = XSSFShape.class.getDeclaredField("anchor");
        f.setAccessible(true);
        f.set(shape, anchor);

        m = XSSFPicture.class.getDeclaredMethod("setPictureReference", PackageRelationship.class);
        m.setAccessible(true);
        m.invoke(shape, rel);
        return shape;
    }

    public static CTOneCellAnchor createOneCellAnchor(XSSFDrawing drawing, XSSFClientAnchor anchor) {
        final int pixel2emu = 12700;
        CTOneCellAnchor ctAnchor = drawing.getCTDrawing().addNewOneCellAnchor();

        long cx = (anchor.getTo().getRowOff()-anchor.getFrom().getRowOff())*pixel2emu;
        long cy = (anchor.getTo().getColOff()-anchor.getFrom().getColOff())*pixel2emu;
        CTPositiveSize2D size = CTPositiveSize2D.Factory.newInstance();
        size.setCx(cx);
        size.setCy(cy);
        ctAnchor.setExt(size);

        ctAnchor.setFrom(anchor.getFrom());
        CTMarker m = ctAnchor.getFrom();
        m.setColOff(m.getColOff()*pixel2emu);
        m.setRowOff(m.getRowOff()*pixel2emu);
        ctAnchor.addNewClientData();
        try {
            Method mt = XSSFClientAnchor.class.getDeclaredMethod("setFrom", CTMarker.class);
            mt.setAccessible(true);
            mt.invoke(anchor, ctAnchor.getFrom());
        } catch (Exception e) {
            throw new RuntimeException("handle me", e);
        }

        return ctAnchor;
    }
}

关于java - 在 Apache POI 3.9 中使用 autosizeColumn 出现在同一列上的图像被拉伸(stretch),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19291948/

相关文章:

java - 将 Swing 应用软件锁定在快捷键上

Excel VBA FSO.GetFolder(folderPath) 在 2007 年但不是 2010 年工作

c# - 无法使用 EPPlus 删除表

java - 使用颜色比例规则的 XSSFSheetConditionalFormatting 不会格式化使用 java 中的 poi 生成的 excel 中的数据

java - 设置首选项(在 PreferenceFragment 内)响应单击

java - 重新实现 mkpasswd

java - 无法使用 Apache POI 打开 Excel

java - 如何使用Java将Excel(2003和2007版本)文件导入到MySQL?

java - 数组子序列的最大可能平均值——需要有效的解决方案

vba - 在工作表 1 的数据下粘贴具有工作表 2 中特定单词的数据