POI插入圖片至Excel使用固定的長寬


使用POI在Excel里插入圖片,如何使插入的圖片使用固定的大小?先介紹原有的兩種方式:

  一種是指定開始和結尾單元格,然后從頭畫到尾,相當於平鋪
  還有一種就是僅指定開始的單元格,圖片的大小跟這個單元格的長寬有關,可以放大縮小固定的倍數,相當於左對齊

第一種效果如下:

 


第二種效果如下:

 


第一種方法的關鍵代碼如下:

 1 private void pictureToSheet(Sheet finalSheet, Row row, Cell cell, int pictureIdx) {
 2     Drawing patriarch = finalSheet.createDrawingPatriarch();
 3     ExcelPositionRange excelPositionRange = ExcelTransferUtils.getMergedRegionPositionRange(finalSheet, row.getRowNum(), cell.getColumnIndex());
 4     ClientAnchor anchor = patriarch.createAnchor(0, 0, 1023, 255,
 5             excelPositionRange.getFirstCol(),
 6             excelPositionRange.getFirstRow(),
 7             excelPositionRange.getLastCol(),
 8             excelPositionRange.getLastRow()
 9     );
10     patriarch.createPicture(anchor, pictureIdx);
11 }

注:代碼中的excelPositionRange,是俺自定義的一個類型。里邊只有四個變量和get/set方法,四個變量分別是單元格的開始、結尾單元格的橫縱坐標。這個大家可以根據需要來改。 

PS:其中1023和255指的是每個單元格被切分的份數,指定的是最后的單元格的最右下角的一個點,其方法的源代碼在本文最后的附錄里。

 

第二種方法的關鍵代碼如下:

 1 private void pictureToSheet(Sheet finalSheet, Row row, Cell cell, int pictureIdx) {
 2     Drawing patriarch = finalSheet.createDrawingPatriarch();
 3     ExcelPositionRange excelPositionRange = ExcelTransferUtils.getMergedRegionPositionRange(finalSheet, row.getRowNum(), cell.getColumnIndex());
 4 
 5     CreationHelper helper = finalSheet.getWorkbook().getCreationHelper();
 6     ClientAnchor anchor = helper.createClientAnchor();
 7 
 8     // 圖片插入坐標
 9     anchor.setCol1(excelPositionRange.getFirstCol());
10     anchor.setRow1(excelPositionRange.getFirstRow());
11 
12     // 使用固定的長寬比例系數
13     double a = 5.9;
14     double b = 1;
15 
16     // 插入圖片
17     Picture pict = patriarch.createPicture(anchor, pictureIdx);
18     pict.resize(a,b);
19 }

 

進階方法:
  在第二種方法的基礎上,可以計算出不同的系數,達到生成圖片都是同一個長寬的功能,從而輸出固定大小的圖片

 1 private void pictureToSheet(Sheet finalSheet, Row row, Cell cell, int pictureIdx) {
 2     Drawing patriarch = finalSheet.createDrawingPatriarch();
 3     ExcelPositionRange excelPositionRange = ExcelTransferUtils.getMergedRegionPositionRange(finalSheet, row.getRowNum(), cell.getColumnIndex());
 4 
 5     CreationHelper helper = finalSheet.getWorkbook().getCreationHelper();
 6     ClientAnchor anchor = helper.createClientAnchor();
 7 
 8     // 圖片插入坐標
 9     anchor.setCol1(excelPositionRange.getFirstCol());
10     anchor.setRow1(excelPositionRange.getFirstRow());
11 
12     // 指定我想要的長寬
13     double standardWidth = 112;
14     double standardHeight = 41;
15 
16     // 計算單元格的長寬
17     double cellWidth = finalSheet.getColumnWidthInPixels(cell.getColumnIndex());
18     double cellHeight = cell.getRow().getHeightInPoints()/72*96;
19 
20     // 計算需要的長寬比例的系數
21     double a = standardWidth / cellWidth;
22     double b = standardHeight / cellHeight;
23 
24     // 插入圖片
25     Picture pict = patriarch.createPicture(anchor, pictureIdx);
26     pict.resize(a,b);
27 }

 PS:這里參考了POI獲取單元格長寬的的方法:http://www.cnblogs.com/acm-bingzi/p/poiWidth.html

 

附錄一
  一般插入圖片的樣例代碼:

 1 // 插入 PNG 圖片至 Excel
 2 String fileName = strAppRootPath + "images/" + "bxlogo.png";
 3 
 4 InputStream is = new FileInputStream(fileName);
 5 byte[] bytes = IOUtils.toByteArray(is);
 6 
 7 int pictureIdx = workbook.addPicture(bytes, Workbook.PICTURE_TYPE_PNG);
 8 
 9 CreationHelper helper = workbook.getCreationHelper();
10 Drawing drawing = sheet.createDrawingPatriarch();
11 ClientAnchor anchor = helper.createClientAnchor();
12 
13 // 圖片插入坐標
14 anchor.setCol1(0);
15 anchor.setRow1(1);
16 // 插入圖片
17 Picture pict = drawing.createPicture(anchor, pictureIdx);
18 pict.resize();

 

附錄二
  patriarch.createAnchor的源代碼跟蹤

 1 /**
 2  * Creates a new client anchor and sets the top-left and bottom-right
 3  * coordinates of the anchor.
 4  * 
 5  * Note: Microsoft Excel seems to sometimes disallow 
 6  * higher y1 than y2 or higher x1 than x2, you might need to 
 7  * reverse them and draw shapes vertically or horizontally flipped! 
 8  *
 9  * @param dx1  the x coordinate within the first cell.
10  * @param dy1  the y coordinate within the first cell.
11  * @param dx2  the x coordinate within the second cell.
12  * @param dy2  the y coordinate within the second cell.
13  * @param col1 the column (0 based) of the first cell.
14  * @param row1 the row (0 based) of the first cell.
15  * @param col2 the column (0 based) of the second cell.
16  * @param row2 the row (0 based) of the second cell.
17  */
18 public HSSFClientAnchor(int dx1, int dy1, int dx2, int dy2, short col1, int row1, short col2, int row2) {
19     super(dx1, dy1, dx2, dy2);
20 
21     checkRange(dx1, 0, 1023, "dx1");
22     checkRange(dx2, 0, 1023, "dx2");
23     checkRange(dy1, 0, 255, "dy1");
24     checkRange(dy2, 0, 255, "dy2");
25     checkRange(col1, 0, MAX_COL, "col1");
26     checkRange(col2, 0, MAX_COL, "col2");
27     checkRange(row1, 0, MAX_ROW, "row1");
28     checkRange(row2, 0, MAX_ROW, "row2");
29 
30     setCol1((short) Math.min(col1, col2));
31     setCol2((short) Math.max(col1, col2));
32     setRow1(Math.min(row1, row2));
33     setRow2(Math.max(row1, row2));
34 
35     if (col1 > col2){
36         _isHorizontallyFlipped = true;
37     }
38     if (row1 > row2){
39         _isVerticallyFlipped = true;
40     }
41 }
View Code

 

  原創文章,歡迎轉載,轉載請注明出處!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM