使用POI在Java Excel中的单元格右侧包含图像

使用POI在Java Excel中的单元格右侧包含图像,java,excel,apache-poi,Java,Excel,Apache Poi,无论如何,可以使用poi通过java将图像移动到excel中单元格的右侧。尝试了所有可能的锚点位置和坐标,但图像仍保留在单元格的左侧 但要求的职位是 以下是用于在java中将图像绘制到excel的代码:- private static void drawImageOnExcelSheet(XSSFSheet sheet, int row, int col, int height, int width, int pictureIdx) throws Exception {

无论如何,可以使用poi通过java将图像移动到excel中单元格的右侧。尝试了所有可能的锚点位置和坐标,但图像仍保留在单元格的左侧

但要求的职位是

以下是用于在java中将图像绘制到excel的代码:-

private static void drawImageOnExcelSheet(XSSFSheet sheet, int row, int col, int height, int width, int pictureIdx)
        throws Exception {

    CreationHelper helper = sheet.getWorkbook().getCreationHelper();

    Drawing drawing = sheet.createDrawingPatriarch();

    ClientAnchor anchor1 = helper.createClientAnchor();
    anchor1.setAnchorType(AnchorType.DONT_MOVE_AND_RESIZE);

    anchor1.setRow2(row); // second anchor determines bottom right position
    anchor1.setCol2(col);
    anchor1.setDx2(Units.toEMU(width)); // dx = left + wanted width
    anchor1.setDy2(Units.toEMU(height)); // dy= top + wanted height

    Picture pic = drawing.createPicture(anchor1, pictureIdx);
    pic.resize();

}

我怀疑您在此处显示的代码取自此答案:。您的代码的注释与此答案中我的代码的注释相同。这导致了这种怀疑

在回答中,您将清楚地看到锚定如何工作,以锚定悬浮在单元格上方的层中的图片


要在单元格的右侧放置内容,需要知道单元格列的宽度。然后,第二个锚点的dx必须设置为与单元格宽度相同的数量。由于dx将添加到列的位置以确定最终位置,因此它将位于单元格的右边缘

但可以肯定的是,您将需要一个双单元格定位点,因此您不应该执行pic.resize,因为双单元格定位点已经确定了大小

例如:

import java.io.*;

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

import org.apache.poi.ss.usermodel.ClientAnchor.AnchorType;
import org.apache.poi.util.IOUtils;
import org.apache.poi.util.Units;

public class ExcelDrawImagesOnCell {

 private static void drawImageOnExcelSheet(XSSFSheet sheet, int row, int col, 
  int picHeight/*in px*/, int picWidth/*in px*/, int pictureIdx, boolean right) throws Exception {

  CreationHelper helper = sheet.getWorkbook().getCreationHelper();

  Drawing drawing = sheet.createDrawingPatriarch();

  ClientAnchor anchor = helper.createClientAnchor();
  anchor.setAnchorType(AnchorType.MOVE_AND_RESIZE);

  int columWidthInPx = Math.round(sheet.getColumnWidthInPixels(col));

  anchor.setCol1(col); //first anchor determines upper left position
  anchor.setRow1(row);
  if (right) {
   anchor.setDx1(Units.pixelToEMU(columWidthInPx) - Units.pixelToEMU(picWidth)); //dx = right - wanted width
   anchor.setDy1(0); //dy = top
  } else {
   anchor.setDx1(0); //dx = left
   anchor.setDy1(0); //dy = top
  }

  anchor.setCol2(col); //second anchor determines bottom right position
  anchor.setRow2(row); 
  if (right) {
   anchor.setDx2(Units.pixelToEMU(columWidthInPx)); //dx = right
   anchor.setDy2(Units.pixelToEMU(picHeight)); //dy = top + wanted height
  } else {
   anchor.setDx2(Units.pixelToEMU(picWidth)); //dx = left + wanted width
   anchor.setDy2(Units.pixelToEMU(picHeight)); //dy = top + wanted height
  }

  drawing.createPicture(anchor, pictureIdx);

 }

 public static void main(String[] args) throws Exception {
  Workbook wb = new XSSFWorkbook();
  Sheet sheet = wb.createSheet();

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

  sheet.setColumnWidth(1, 15*256); //set the column width to 15 character widths
  for (int r = 0; r < 10; r++ ) {
   sheet.createRow(r).createCell(1).setCellValue("Picture " + (r+1));
   //drawImageOnExcelSheet((XSSFSheet)sheet, r, 1, 16/*px*/, 16/*px*/, pictureIdx, false);
   drawImageOnExcelSheet((XSSFSheet)sheet, r, 1, 16/*px*/, 16/*px*/, pictureIdx, true/*right*/);
  }

  wb.write(new FileOutputStream("ExcelDrawImagesOnCell.xlsx"));
  wb.close();
 }
}
结果:


您是否尝试过使用dx1、dy1、dx2、dy2?是的,但它仍然只保留在左侧。我也不确定在同一个单元格内使用的坐标。要在单元格右侧放置某些东西,您需要知道单元格列的宽度。然后必须设置Dx2。setDx2Units.toEMUwidthOfCellInPoints或.setDx2Units.pixelToEMUwidthOfCellInPixels.Axel,尝试您建议的选项,如下drawImageOnExcelSheetXSSFSheet sheet,row,i,40,sheet.getColumnWidthInPixelsi,pictureIdx1;锚定设置如下:锚定1.setRow2row;anchor1.setCol2col;anchor1.setDx2Units.pixelToEMUint宽度;锚点1.SETDY2单位至高度;Picture pic=drawing.createPictureanchor1,pictureIdx;pic.调整大小;但它不起作用。除了x2,我还需要设置其他位置吗?Axel我还有一个问题。我正在使用HSSFWorkbook,其中Units.pixelToEMU不起作用,并且我有sheet.getColumnWidth和not width(以像素为单位)。在这种情况下,我应该如何处理单位转换?我应该使用什么标准单位?@viji shetty:请参阅我的补充。非常感谢@Axel。这真是帮了大忙。
import java.io.*;

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

import org.apache.poi.ss.usermodel.ClientAnchor.AnchorType;
import org.apache.poi.util.IOUtils;
import org.apache.poi.util.Units;

public class ExcelDrawImagesOnCell {

 private static void drawImageOnExcelSheet(Sheet sheet, int row, int col, 
  int picHeight/*in px*/, int picWidth/*in px*/, int pictureIdx, boolean right) throws Exception {

  int DEFAULT_COL_WIDTH = 10 * 256; // 1/256th of a character width
  float DEFAULT_ROW_HEIGHT = 12.75f; //255 twips = 12.75 pt

  Row rowObject = sheet.getRow(row);
  float rowHeight = (rowObject!=null)?rowObject.getHeightInPoints():DEFAULT_ROW_HEIGHT;

  CreationHelper helper = sheet.getWorkbook().getCreationHelper();

  Drawing drawing = sheet.createDrawingPatriarch();

  ClientAnchor anchor = helper.createClientAnchor();
  anchor.setAnchorType(AnchorType.MOVE_AND_RESIZE);

  int columWidthInPx = Math.round(sheet.getColumnWidthInPixels(col));
  int columWidth = sheet.getColumnWidth(col); // 1/256th of a character width

  anchor.setCol1(col); //first anchor determines upper left position
  anchor.setRow1(row);
  if (sheet instanceof XSSFSheet) {
   if (right) {
    anchor.setDx1(Units.pixelToEMU(columWidthInPx) - Units.pixelToEMU(picWidth)); //dx = right - wanted width
    anchor.setDy1(0); //dy = top
   } else {
    anchor.setDx1(0); //dx = left
    anchor.setDy1(0); //dy = top
   }
  } else if (sheet instanceof HSSFSheet) {
   if (right) {
    anchor.setDx1((int)Math.round(
     Units.DEFAULT_CHARACTER_WIDTH / 256f * 14.75 * DEFAULT_COL_WIDTH //right = constant for all possible column widths
     -
     picWidth * 14.75 * DEFAULT_COL_WIDTH / columWidth //wanted width = in relation to column width
    )); //dx = right - wanted width

    anchor.setDy1(0); //dy = top
   } else {
    anchor.setDx1(0); //dx = left
    anchor.setDy1(0); //dy = top
   }
  }

  anchor.setCol2(col); //second anchor determines bottom right position
  anchor.setRow2(row); 
  if (sheet instanceof XSSFSheet) {
   if (right) {
    anchor.setDx2(Units.pixelToEMU(columWidthInPx)); //dx = right
    anchor.setDy2(Units.pixelToEMU(picHeight)); //dy = top + wanted height
   } else {
    anchor.setDx2(Units.pixelToEMU(picWidth)); //dx = left + wanted width
    anchor.setDy2(Units.pixelToEMU(picHeight)); //dy = top + wanted height
   }
  } else if (sheet instanceof HSSFSheet) {
   if (right) {
    anchor.setDx2((int)Math.round(Units.DEFAULT_CHARACTER_WIDTH / 256f * 14.75 * DEFAULT_COL_WIDTH)); //dx = right = constant for all possible column widths
    anchor.setDy2((int)Math.round(picHeight * 14.75 * DEFAULT_ROW_HEIGHT / rowHeight)); //dy = top + wanted height
   } else {
    anchor.setDx2((int)Math.round(picWidth * 14.75 * DEFAULT_COL_WIDTH / columWidth)); //dx = left + wanted width
    anchor.setDy2((int)Math.round(picHeight * 14.75 * DEFAULT_ROW_HEIGHT / rowHeight)); //dy = top + wanted height
   }
  }

  drawing.createPicture(anchor, pictureIdx);

 }

 public static void main(String[] args) throws Exception {
  //Workbook wb = new XSSFWorkbook();
  Workbook wb = new HSSFWorkbook();
  Sheet sheet = wb.createSheet();

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

  sheet.setColumnWidth(1, 20*256); //set the column width to 20 character widths
  for (int r = 0; r < 10; r++ ) {
   sheet.createRow(r).createCell(1).setCellValue("    Picture " + (r+1));
   if ((r % 2) == 0) {
    drawImageOnExcelSheet(sheet, r, 1, 16/*px*/, 16/*px*/, pictureIdx, false);
   } else {
    drawImageOnExcelSheet(sheet, r, 1, 16/*px*/, 16/*px*/, pictureIdx, true/*right*/);
   }
  }

  if (wb instanceof XSSFWorkbook) {
   wb.write(new FileOutputStream("ExcelDrawImagesOnCell.xlsx"));
  } else if (wb instanceof HSSFWorkbook) {
   wb.write(new FileOutputStream("ExcelDrawImagesOnCell.xls"));
  }
  wb.close();
 }
}