POI - Excel 单元格中图像的固定宽度

时间:2021-06-01 14:44:27

标签: apache-poi

我按照 approach 添加了带有 POI 的新图像。

    cell.getRow().setHeight(img.getHeightForExcel());
    sheet.setColumnWidth(cell.getColumnIndex(), img.getWidthForExcel());

    final int picID = workBook.addPicture(bytes, Workbook.PICTURE_TYPE_PNG);
    /* Create the drawing container */
    final XSSFDrawing drawing = (XSSFDrawing) sheet.createDrawingPatriarch();

    // ========adding image START
    final XSSFClientAnchor myAnchor = new XSSFClientAnchor();
    myAnchor.setAnchorType(AnchorType.DONT_MOVE_AND_RESIZE);
    /* Define top left corner, and we can resize picture suitable from there */
    myAnchor.setCol1(cell.getColumnIndex()); // Column start
    myAnchor.setRow1(rowNum - 1); // Row start
    myAnchor.setCol2(cell.getColumnIndex() + 2); // Column end (covers two columns)
    myAnchor.setRow2(rowNum); // Row end

    /* Invoke createPicture and pass the anchor point and ID */
    final XSSFPicture myPicture = drawing.createPicture(myAnchor, picID);

原则上这很有效。我在开头用图像的宽度指定列的宽度。 (高度也是)。

我面临的主要问题是,只要我像 autoadjust 一样运行

    for (; i < max; i++) {
        xlsWorkbook.getSheet().autoSizeColumn(i);
    }

我遇到了前两列也被调整大小的问题。但是这样图像的宽度也会调整大小。由于宽度可能很长(或很窄),我不想影响图像大小。

有没有办法设置图片的宽度,而不是列宽?

1 个答案:

答案 0 :(得分:2)

如果您不想在列宽更改时调整图像大小,则不能使用该方法。这种方法明确说明图像的大小应与其锚定的单元格大小相同。因此,如果单元格大小发生变化,图片大小也会发生变化。

您可能认为 ClientAnchor.AnchorType.DONT_MOVE_AND_RESIZE 应该防止图像调整大小。但这仅在 Excel GUI 中打开时才有价值。 Apache poi 在自动调整列大小时不尊重 ClientAnchor.AnchorType。可能这会在以后的版本中改变。但在当前版本 apache poi 5.0.0 中没有。

因此,为了满足您的要求,您只设置了一个单元格锚点。那只是anchor.setCol1anchor.setRow1作为图片的左上角位置。然后您需要稍后调整图片大小以设置右下角位置。您必须在设置所有列宽和行高之后调整大小。所以之后自动调整列的大小。否则调整列大小会再次调整图片大小。

完整示例:

import org.apache.poi.xssf.usermodel.*;
import org.apache.poi.ss.usermodel.*;

import org.apache.poi.util.IOUtils;

import java.io.InputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;


class ImageTest {

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

  Workbook wb = new XSSFWorkbook();
  Sheet sheet = wb.createSheet("My Sample Excel");
  //FileInputStream obtains input bytes from the image file
  InputStream inputStream = new FileInputStream("./logo.png");
  //Get the contents of an InputStream as a byte[].
  byte[] bytes = IOUtils.toByteArray(inputStream);
  //Adds a picture to the workbook
  int pictureIdx = wb.addPicture(bytes, Workbook.PICTURE_TYPE_PNG);
  //close the input stream
  inputStream.close();
  //Returns an object that handles instantiating concrete classes
  CreationHelper helper = wb.getCreationHelper();
  //Creates the top-level drawing patriarch.
  Drawing drawing = sheet.createDrawingPatriarch();

  //Create an anchor that is attached to the worksheet
  ClientAnchor anchor = helper.createClientAnchor();
  
  //Set anchor type; only valuable in Excel GUI  
  anchor.setAnchorType(ClientAnchor.AnchorType.MOVE_DONT_RESIZE);

  //Create an anchor with upper left cell only
  anchor.setCol1(1); //Column B
  anchor.setRow1(2); //Row 3

  //Create a picture
  Picture pict = drawing.createPicture(anchor, pictureIdx);
   
  //Reset the image to the original size
  //pict.resize(); // don't do this before autosize column

  //Create cell in column B to auto sizing that column
  Cell cell = sheet.createRow(0).createCell(1);
  cell.setCellValue("12345678901234567890");

  sheet.autoSizeColumn(1);
  
  //Reset the image to the original size
  //pict.resize();
  //Reset the image to half the original size
  pict.resize(0.5);

  //Write the Excel file
  FileOutputStream fileOut = null;
  fileOut = new FileOutputStream("./myFile.xlsx");
  wb.write(fileOut);
  fileOut.close();

 }
}
相关问题