Apache POI-HSSF искажает размер изображения при добавлении изображения в ячейку Excel

Я добавляю картинку в ячейку с помощью Apache POI-HSSF. Размер изображения 120x100, но независимо от того, что я делаю и как меняю его размер, таблица Excel всегда показывает, что оно занимает несколько строк, и искажает его до гораздо большей высоты, чем ширины.

Как сохранить исходный размер?

Мой код:

InputStream is = new FileInputStream(getImageURL());
byte[] bytes = IOUtils.toByteArray(is);
int pictureIdx = wb.addPicture(bytes, Workbook.PICTURE_TYPE_JPEG);
is.close();

//add a picture shape
CreationHelper helper = wb.getCreationHelper();
ClientAnchor anchor = helper.createClientAnchor();
// Create the drawing patriarch.  This is the top level container for all shapes.
Drawing drawing = sheet1.createDrawingPatriarch();
//set top-left corner of the picture,
//subsequent call of Picture#resize() will operate relative to it

anchor.setAnchorType(0);
anchor.setCol1(1);
anchor.setRow1(1);

Picture pict = drawing.createPicture(anchor, pictureIdx);

//auto-size picture relative to its top-left corner
pict.resize();

Я пробовал все координаты dx / dy и Col / Row. Положение не имеет значения, проблема в том, что изображение растягивается по горизонтали.


person gene b.    schedule 24.04.2013    source источник
comment
Я обнаружил, что это происходит, когда я устанавливаю высоту строки с помощью row.setHeight (). Если я этого не сделаю, изображение в порядке. Независимо от того, насколько большой я делаю высоту, изображение все равно растягивается по вертикали.   -  person gene b.    schedule 24.04.2013


Ответы (4)


Я столкнулся с аналогичной проблемой, когда добавленное мной изображение искажалось. Я пробовал pict.resize () и sheet.autoSizeColumn (), но это не сработало. Наконец, я нашел следующий URL: - https://svn.apache.org/repos/asf/poi/trunk/src/examples/src/org/apache/poi/examples/ss/AddDimensionedImage.java

Я добавил вышеуказанный класс в свой код и использовал его метод для добавления изображения в Excel. Мне удалось добавить изображение с небольшим искажением. Надеюсь, это поможет и вам. Я написал ниже код: -

BufferedImage imageIO = ImageIO.read(new URL(image));
int height= imageIO.getHeight();
int width=imageIO.getWidth();
int relativeHeight=(int)(((double)height/width)*28.5);
new AddDimensionedImage().addImageToSheet(2,  sheet.getPhysicalNumberOfRows()-1 , sheet, sheet.createDrawingPatriarch(),new URL(image), 30, relativeHeight, AddDimensionedImage.EXPAND_ROW);
person Abhishek K    schedule 20.01.2016
comment
Кажется, что файл AddDimensionedImage.java переместился. Новый URL: svn.apache.org/repos/asf/poi/trunk/src/examples/src/org/apache/ - person S. Doe; 13.11.2020

Насколько я понял из документации Apache POI, это из-за pict.resize();, как говорится, здесь, что если размер шрифта по умолчанию для книги был изменен, изображение могло растянуться по вертикали или горизонтали.

person hasanoviz    schedule 07.08.2013

У меня такая же проблема, и я решил скопировать этот класс в свой проект AddDimensionedImage, а затем использовал этот метод.

protected void addImageInCell(Sheet sheet, URL url, Drawing<?> drawing, int colNumber, int rowNumber) {
    BufferedImage imageIO = ImageIO.read(url);
    int height = imageIO.getHeight();
    int width = imageIO.getWidth();
    int relativeHeight = (int) (((double) height / width) * 28.5);
    new AddDimensionedImage().addImageToSheet(colNumber, rowNumber, sheet, drawing, url, 30, relativeHeight,
            AddDimensionedImage.EXPAND_ROW_AND_COLUMN);

}

вы можете вызвать этот метод со следующей строкой:

URL url = new URL("https://blog.expedia.mx/por-que-los-viajeros-internacionales-visitan-mexico/");
addImageInCell(sheet, url, sheet.createDrawingPatriarch(), 0, 0);
person Jesús Sánchez    schedule 28.03.2018
comment
Кажется, что файл AddDimensionedImage.java переместился. Новый URL: svn.apache.org/repos/asf/poi/trunk/src/examples/src/org/apache/ - person S. Doe; 13.11.2020

Я создал еще одно пустое изображение шириной, взятой из sheet.getColumnWidthInPixels, нарисовал поверх него необходимое изображение и использовал AddDimensionedImage.EXPAND_ROW_AND_COLUMN, чтобы оно точно поместилось в ячейку:

    HSSFRow imageRow = sheet.createRow(row);

    BufferedImage image = ImageIO.read(Paths.get(pathToImage).toUri().toURL());

    AddDimensionedImage addImage = new AddDimensionedImage();
    float columnWidth = sheet.getColumnWidthInPixels(0);

    BufferedImage off_Image = new BufferedImage((int) columnWidth, actualImageHeight, BufferedImage.TYPE_INT_RGB);
    Graphics2D g2 = off_Image.createGraphics();
    g2.setColor(new Color(192,192,192));
    g2.fillRect(0, 0, off_Image.getWidth(), off_Image.getHeight());
    g2.drawImage(image, 0, 0, null);
    g2.dispose();

    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ImageIO.write(off_Image, "jpg", baos);
    byte[] bytes = baos.toByteArray();

    double reqImageWidthMM = ((double) off_Image.getWidth()) / ConvertImageUnits.PIXELS_PER_MILLIMETRES;
    double reqImageHeightMM = ((double) off_Image.getHeight()) / ConvertImageUnits.PIXELS_PER_MILLIMETRES;

    addImage.addImageToSheet("A1", sheet, bytes, reqImageWidthMM, reqImageHeightMM, AddDimensionedImage.EXPAND_ROW_AND_COLUMN);

Мне пришлось скопировать AddDimensionedImage.java в мой путь к классам и перегрузить addImageToSheet, чтобы принять массив байтов.

До этого я пробовал другие варианты, упомянутые здесь, но это не помогло. Надеюсь, мой ответ будет кому-то полезен.

person Vitaly Sazanovich    schedule 01.02.2018
comment
Кажется, что файл AddDimensionedImage.java переместился. Новый URL: svn.apache.org/repos/asf/poi/trunk/src/examples/src/org/apache/ - person S. Doe; 13.11.2020