[英]Apache POI write image and text excel
我在同一單元格中寫入圖像和文本時遇到麻煩,並且在excel和POI Excel HSSFPicture Image和ALT TEXT中 在同一單元格中添加圖像和文本時遇到了與StackOverflow類似的問題,但是預期的輸出不同,我無法弄清楚是什么錯誤用我的代碼? 和預期的輸出如下
這是我的代碼;
Workbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet("Sheet1");
//FileInputStream obtains input bytes from the image file
InputStream inputStream = new FileInputStream(k_pipe_img_file);
//Get the contents of an InputStream as a byte[].
byte[] bytes = IOUtils.toByteArray(inputStream);
//Adds a picture to the workbook
int pictureIdx = workbook.addPicture(bytes, Workbook.PICTURE_TYPE_PNG);
//close the input stream
inputStream.close();
//Returns an object that handles instantiating concrete classes
CreationHelper helper = workbook.getCreationHelper();
//Creates the top-level drawing patriarch.
Drawing drawing = sheet.createDrawingPatriarch();
ClientAnchor anchor1 = new XSSFClientAnchor();
anchor1.setAnchorType(ClientAnchor.AnchorType.DONT_MOVE_AND_RESIZE);
anchor1.setCol1(1);
anchor1.setCol2(1);
anchor1.setRow1(2);
anchor1.setRow2(2);
//Creates a picture
Picture pict = drawing.createPicture(anchor1, pictureIdx);
pict.resize(1, 1);
Row row = sheet.createRow(2);
row.setHeight((short) 4000);
sheet.setColumnWidth(0, 4000);
Cell cell = row.createCell(0, CellType.STRING);
cell.setCellValue("Task 1");
sheet.setColumnWidth(1, 5000);
cell = row.createCell(1, CellType.STRING);
cell.setCellValue("Replace Kemplon-Pipe");
CellStyle style=row.getSheet().getWorkbook().createCellStyle();
style.setVerticalAlignment(VerticalAlignment.TOP);
cell.setCellStyle(style);
//Write the Excel file
FileOutputStream fileOut = new FileOutputStream(k_Task_file);
workbook.write(fileOut);
fileOut.close();
圖像占據整個單元格,文本位於圖像后面。
有沒有可能的解決方案?
在Excel
表中,圖片不在單元格中,而是懸停在單元格上方的一層中。 它們以以下方式錨定到單元:
一個單元格錨點確定圖片的左上位置。 如果使用圖片,則必須將其尺寸調整為原始尺寸。
兩個單元格的錨點確定圖片的左上位置和大小。 第一錨確定左上位置,第二錨確定右下位置。 因此,給出了圖片的大小。
每個錨點可以具有給定的行和列,還可以具有dx
和dy
。 dx
和dy
將添加到列和行的位置,以確定最終位置。 dx
和dy
的度量單位是EMU
。 Apache poi提供org.apache.poi.util.Units來根據點或像素來計算EMU
。
問題之一是apache poi有一種方法以像素為單位來獲取列的寬度,而它只有一種方法以點為單位來獲取行的高度。 因此,我們要考慮兩個不同的度量單位。
另一個問題是,如果我們要考慮圖片的長寬比,則需要首先確定圖片文件的原始大小。 如何使用Java獲取jpg文件的本機尺寸有很多問題/答案。 我認為所有答案都非常復雜,沒有一個是很好的答案。
下面的示例確實在單元格B3
上定位了圖片,該圖片在距左單元格邊界20px,距頂部單元格邊界20pt,距右側單元格邊界20 px,高度距底部單元格邊界10pt的位置錨定。
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 ExcelDrawImagesOverCell {
private static void drawImageOnExcelSheet(XSSFSheet sheet, int row, int col,
int left/*in px*/, int top/*in pt*/, int width/*in px*/, int height/*in pt*/, int pictureIdx) throws Exception {
CreationHelper helper = sheet.getWorkbook().getCreationHelper();
Drawing drawing = sheet.createDrawingPatriarch();
ClientAnchor anchor = helper.createClientAnchor();
anchor.setAnchorType(AnchorType.MOVE_AND_RESIZE);
anchor.setCol1(col); //first anchor determines upper left position
anchor.setRow1(row);
anchor.setDx1(Units.pixelToEMU(left)); //dx = left in px
anchor.setDy1(Units.toEMU(top)); //dy = top in pt
anchor.setCol2(col); //second anchor determines bottom right position
anchor.setRow2(row);
anchor.setDx2(Units.pixelToEMU(left + width)); //dx = left + wanted width in px
anchor.setDy2(Units.toEMU(top + height)); //dy= top + wanted height in pt
drawing.createPicture(anchor, pictureIdx);
}
public static void main(String[] args) throws Exception {
Workbook wb = new XSSFWorkbook();
CellStyle styleVertAlingTop = wb.createCellStyle();
styleVertAlingTop.setVerticalAlignment(VerticalAlignment.TOP);
Sheet sheet = wb.createSheet();
sheet.setColumnWidth(0, 15 * 256); //15 default characters width
sheet.setColumnWidth(1, 30 * 256); //30 default characters width
Row row = sheet.createRow(2);
row.setHeight((short)(100 * 20)); //100pt height * 20 = twips (twentieth of an inch point)
Cell cell = row.createCell(0);
cell.setCellValue("Task 1");
cell = row.createCell(1);
cell.setCellValue("Replace Kemplon-Pipe");
cell.setCellStyle(styleVertAlingTop);
InputStream is = new FileInputStream("samplePict.jpeg");
byte[] bytes = IOUtils.toByteArray(is);
int pictureIdx = wb.addPicture(bytes, Workbook.PICTURE_TYPE_JPEG);
is.close();
int left = 20; // 20px
int top = 20; // 20pt
int width = Math.round(sheet.getColumnWidthInPixels(1) - left - left); //width in px
int height = Math.round(row.getHeightInPoints() - top - 10/*pt*/); //height in pt
drawImageOnExcelSheet((XSSFSheet)sheet, 2, 1, left, top, width, height, pictureIdx);
wb.write(new FileOutputStream("ExcelDrawImagesOverCell.xlsx"));
wb.close();
}
}
結果:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.