(解決)easypoi圖片導出只佔用一個單元格

@java

前提

本解決方案來源於網絡,因解決本身需求,所以自行記錄起來,若有侵權請聯繫我。網絡

依賴環境

easypoi——依賴版本3.1.0this

問題緣由

easypoi源代碼中建立圖片的方法中,沒有對圖片合併單元格後計算單元格合併,僅僅是計算圖片所在的一個單元格位置,所以只填充一個單元格。excel

/**
 * 圖片類型的Cell
 */
public void createImageCell(Cell cell, double height,
                            String imagePath, byte[] data) throws Exception {
    if (height > cell.getRow().getHeight()) {
        cell.getRow().setHeight((short) height);
    }
    ClientAnchor anchor;
    if (type.equals(ExcelType.HSSF)) {
        anchor = new HSSFClientAnchor(0, 0, 0, 0, (short) cell.getColumnIndex(), cell.getRow().getRowNum(), (short) (cell.getColumnIndex() + 1),
                cell.getRow().getRowNum() + 1);
    } else {
        anchor = new XSSFClientAnchor(0, 0, 0, 0, (short) cell.getColumnIndex(), cell.getRow().getRowNum(), (short) (cell.getColumnIndex() + 1),
                cell.getRow().getRowNum() + 1);
    }
    if (StringUtils.isNotEmpty(imagePath)) {
        data = ImageCache.getImage(imagePath);
    }
    if (data != null) {
        PoiExcelGraphDataUtil.getDrawingPatriarch(cell.getSheet()).createPicture(anchor,
                cell.getSheet().getWorkbook().addPicture(data, getImageType(data)));
    }
}

解決方案

對上述代碼進行重寫code

/**
     * 圖片類型的Cell
     */
public void createImageCell(Cell cell, double height,
                                String imagePath, byte[] data) throws Exception {
    if (height > cell.getRow().getHeight()) {
        cell.getRow().setHeight((short) height);
    }
    
    //重寫部分開始
    //獲取當前單元格所在的sheet
    Sheet sheet = cell.getRow().getSheet();
    //獲取當前sheet頁中的全部合併單元格信息
    List<CellRangeAddress> mergedRegions = sheet.getMergedRegions();
    //獲取當前單元格的開始列號
    int firstColumn = (short)cell.getColumnIndex();
    //獲取當前單元格的開始行號
    int firstRow = cell.getRow().getRowNum();
    //獲取當前單元格的結束列號
    int lastColumn = (short)(cell.getColumnIndex());
    //獲取當前單元格的結束行號
    int lastRow = cell.getRow().getRowNum();
    for(CellRangeAddress mergedRegion : mergedRegions){
        //判斷當前單元格是否包含合併行或和並列 當前單元格的全部行號和列號都包含在合併域內 則認爲當前單元格存在合併行或和並列
        if(cell.getColumnIndex()>=mergedRegion.getFirstColumn()
                && cell.getColumnIndex()<=mergedRegion.getLastColumn()
                && cell.getRow().getRowNum()>=mergedRegion.getFirstRow()
                && cell.getRow().getRowNum()<=mergedRegion.getLastRow()){
            //獲取合併域的開始行號
            firstRow = mergedRegion.getFirstRow();
            //獲取合併域的結束行號
            lastRow = mergedRegion.getLastRow();
            //獲取合併域的開始列號
            firstColumn = mergedRegion.getFirstColumn();
            //獲取合併域的結束列號
            lastColumn = mergedRegion.getLastColumn();
            break;
        }
    }
    //重寫部分結束

    ClientAnchor anchor;

    if(this.type.equals(ExcelType.HSSF)) {
    	//重寫前
    	//anchor = new HSSFClientAnchor(0, 0, 0, 0, (short) cell.getColumnIndex(), cell.getRow().getRowNum(), (short) (cell.getColumnIndex() + 1), cell.getRow().getRowNum() + 1);
    	//重寫後
        anchor = new HSSFClientAnchor(0, 0, 0, 0, (short)firstColumn, firstRow, (short)(lastColumn+1), lastRow+1);
    } else {
    	//重寫前
    	//anchor = new XSSFClientAnchor(0, 0, 0, 0, (short) cell.getColumnIndex(), cell.getRow().getRowNum(), (short) (cell.getColumnIndex() + 1), cell.getRow().getRowNum() + 1);
    	//重寫後
        anchor = new XSSFClientAnchor(0, 0, 0, 0, (short)firstColumn, firstRow, (short)(lastColumn+1), lastRow+1);
    }

    if(StringUtils.isNotEmpty(imagePath)) {
        data = ImageCache.getImage(imagePath);
    }

    if(data != null) {
        PoiExcelGraphDataUtil.getDrawingPatriarch(cell.getSheet()).createPicture((ClientAnchor)anchor, cell.getSheet().getWorkbook().addPicture(data, this.getImageType(data)));
    }
}

重寫jar中的方法

  1. 找到要重寫的方法所在的包,如上述方法所在的包爲
package cn.afterturn.easypoi.excel.export.base;
  1. 在src目錄下,建立新建一個同包名同類名的類
  2. 將源代碼完整的複製到新建立的類
  3. 在新建立的類中,修改對應的要重寫的方法中的代碼(注意不要刪除原有的方法以及參數,可是能夠新增一些方法)

原理

編譯輸出的時候會優先使用咱們src下面的類,而不是優先使用Jar包裏面的類,這樣就達到了覆蓋jar包方法的目的。圖片

相關文章
相關標籤/搜索