Apache POI:使用“源表”中的“合并列”将数据复制到特定单元格中的特定工作表

时间:2017-11-21 04:56:22

标签: apache-poi

问题

如何使用Apache POI(XSSF格式)将源Excel工作表的某些部分数据添加到目标Excel工作表?Excel工作表包含合并列。

要求:

  1. 要求不仅要复制行,还要将数据放入目标工作表的所需Excel单元格(所需列)。
  2. 注意

    可以实现在目标Excel工作表中将行插行到所需的行位置。问题是首先根据目标表中的源表合并单元格,然后将数据放入所需的合并的Excel单元格中。 - 合并列可能会连续变化。

    这是源代码,半参考和半写。

    public static void copyNodeFrmtSrcToDest(XSSFSheet srcSheet, XSSFSheet destSheet, XSSFRow srcRowStart,XSSFRow srcRowEnd
            ,XSSFRow destRowStart, int destCellStart, Map<Integer, XSSFCellStyle> styleMap){
    
        /*Check if there is only one row to be pasted*/
        int noOfRows = srcRowEnd.getRowNum() - srcRowStart.getRowNum();
        /*Check if there is only one row to be pasted*/
        if(noOfRows == 0)
        {
            /*Copy a single row*/
            copyRow(srcSheet,destSheet,srcRowStart,destRowStart,destCellStart,styleMap);
            return;
        }
        for (int i = 0;i <= noOfRows ;i++)//For every row
        {
            /*Get rows from source sheet and increment it*/
            XSSFRow srcIntermediateRow =  srcSheet.getRow(srcRowStart.getRowNum() + i);
            if(destRowStart == null)
            {
                try {
                    throw new RowNotFoundError("Row has not been found in the sheet.Kindly create a row.");
                } catch (RowNotFoundError e) {
                    e.printStackTrace();
                    System.out.println(e.toString());
                }
            }
            if(i!=0)//Assuming destRowStart has been created by user of the API
            {
                /*Create a new row*/
                destRowStart = destSheet.createRow(destRowStart.getRowNum()+1);
            }
            copyRow(srcSheet,destSheet,srcIntermediateRow,destRowStart,destCellStart,styleMap);
        }
    }
    
    public static void copyRow(XSSFSheet srcSheet, XSSFSheet destSheet, XSSFRow srcRow, XSSFRow destRow, int destCellStart,
            Map<Integer, XSSFCellStyle> styleMap) {
        int count = 1;
        Set<CellRangeAddress> mergedRegions = new HashSet<CellRangeAddress>();
        CellRangeAddress previousMergedRegion =null;
        destRow.setHeight(srcRow.getHeight());
        for (int j = srcRow.getFirstCellNum(); j <= srcRow.getLastCellNum(); j++) {
            int mergedDiff;
            XSSFCell oldCell = srcRow.getCell(j);
            XSSFCell newCell;
            if(j == srcRow.getFirstCellNum()){
            newCell = destRow.getCell(destCellStart);}
            else
            {
                newCell = destRow.getCell(destCellStart + count);
    
            }
            if (oldCell != null) {
                if (newCell == null) {
                    if(j == srcRow.getFirstCellNum()){
                    newCell = destRow.createCell(destCellStart);//Keeping the new cell as the first one.
                    copyCell(oldCell, newCell, styleMap);
                    }
                    else{
                        newCell = destRow.createCell(destCellStart + count);
                        count = count + 1;
                        copyCell(oldCell, newCell, styleMap);}
                }
    
                CellRangeAddress mergedRegion = getMergedRegion(srcSheet, srcRow.getRowNum(),oldCell.getColumnIndex());
                if(previousMergedRegion != null && mergedRegion != null)
                {
    
                    mergedDiff = mergedRegion.getLastColumn() - mergedRegion.getFirstColumn();
                    if(!previousMergedRegion.equals(mergedRegion))
                    {
                        destCellStart = destCellStart + mergedDiff + 1;
                        count = 1;
                    }
                }
                if (mergedRegion != null) {
                    previousMergedRegion = mergedRegion.copy();
                    mergedDiff = mergedRegion.getLastColumn() - mergedRegion.getFirstColumn();
                    CellRangeAddress newMergedRegion = new CellRangeAddress(destRow.getRowNum(),destRow.getRowNum()
                            ,destCellStart,destCellStart + mergedDiff);
    
                    if (isNewMergedRegion(newMergedRegion, mergedRegions))
                    {
                        mergedRegions.add(newMergedRegion);
                        destSheet.addMergedRegion(newMergedRegion);
                    }
    
                }
            }
        }
    
    }
    
    public static void copyCell(XSSFCell oldCell, XSSFCell newCell, Map<Integer, XSSFCellStyle> styleMap) {
        if(styleMap != null) {
            if(oldCell.getSheet().getWorkbook() == newCell.getSheet().getWorkbook()){
                newCell.setCellStyle(oldCell.getCellStyle());
            } else{
                int stHashCode = oldCell.getCellStyle().hashCode();
                XSSFCellStyle newCellStyle = styleMap.get(stHashCode);
                if(newCellStyle == null){
                    newCellStyle = newCell.getSheet().getWorkbook().createCellStyle();
                    newCellStyle.cloneStyleFrom(oldCell.getCellStyle());
                    styleMap.put(stHashCode, newCellStyle);
                }
                newCell.setCellStyle(newCellStyle);
            }
        }
        switch(oldCell.getCellTypeEnum()) {
            case STRING:
                newCell.setCellValue(oldCell.getStringCellValue());
                break;
            case NUMERIC:
                newCell.setCellValue(oldCell.getNumericCellValue());
                break;
            case BLANK:
                newCell.setCellValue(oldCell.getStringCellValue());
                break;
            case BOOLEAN:
                newCell.setCellValue(oldCell.getBooleanCellValue());
                break;
            case ERROR:
                newCell.setCellErrorValue(oldCell.getErrorCellValue());
                break;
            case FORMULA:
                newCell.setCellFormula(oldCell.getCellFormula());
                break;
            default:
                break;
        }
    
    }
    
    public static CellRangeAddress getMergedRegion(XSSFSheet sheet, int rowNum, int cellNum) {
        for (int i = 0; i < sheet.getNumMergedRegions(); i++) {
            CellRangeAddress merged = sheet.getMergedRegion(i);
            if (merged.isInRange(rowNum, cellNum)) {
                return merged;
            }
        }
        return null;
    }
    private static boolean isNewMergedRegion(CellRangeAddress newMergedRegion, Set<CellRangeAddress> mergedRegions)
    {
        if(mergedRegions.isEmpty())
        {
            return true;
        }
        return !mergedRegions.contains(newMergedRegion);
    }
    

    }

    它适用于某些测试用例,但并非适用于所有测试用例。

0 个答案:

没有答案