All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.swiftboot.sheet.util.PoiUtils Maven / Gradle / Ivy

There is a newer version: 2.4.7
Show newest version
package org.swiftboot.sheet.util;

import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.WorkbookUtil;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.swiftboot.collections.Matrix;
import org.swiftboot.sheet.constant.SheetFileType;
import org.swiftboot.sheet.meta.Area;
import org.swiftboot.sheet.meta.Picture;
import org.swiftboot.sheet.meta.Position;
import org.swiftboot.sheet.meta.SheetId;

import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * @author swiftech
 */
public class PoiUtils {

    /**
     * Get first sheet from a worksheet file by it's suffix
     *
     * @param templateFileStream
     * @param fileSuffix
     * @return
     * @throws IOException
     */
    public static Sheet firstSheet(InputStream templateFileStream, String fileSuffix) throws IOException {
        Workbook workbook = initWorkbook(templateFileStream, fileSuffix);
        return firstSheet(workbook);
    }

    /**
     * Get first sheet of workbook, create new if not existed.
     *
     * @param workbook
     * @return
     */
    public static Sheet firstSheet(Workbook workbook) {
        int sheetCount = workbook.getNumberOfSheets();
        if (sheetCount <= 0) {
            return workbook.createSheet();
        }
        else {
            return workbook.getSheetAt(0);
        }
    }

    /**
     * Get sheet from a worksheet file by it's suffix
     *
     * @param templateFileStream
     * @param fileSuffix
     * @return
     * @throws IOException
     */
    public static Sheet getSheet(InputStream templateFileStream, String fileSuffix, int sheetIdx) throws IOException {
        Workbook workbook = initWorkbook(templateFileStream, fileSuffix);
        return getSheet(workbook, sheetIdx);
    }

    /**
     * Get sheet of workbook by index.
     *
     * @param workbook
     * @param sheetIdx
     * @return
     */
    public static Sheet getSheet(Workbook workbook, int sheetIdx) {
        int sheetCount = workbook.getNumberOfSheets();
        if (sheetCount <= sheetIdx) {
            return null;
        }
        else {
            return workbook.getSheetAt(sheetIdx);
        }
    }

    /**
     * Get sheet of workbook by name.
     *
     * @param workbook
     * @param sheetId
     * @return
     */
    public static Sheet getSheet(Workbook workbook, SheetId sheetId) {
        if (sheetId.getSheetIndex() != null && sheetId.getSheetIndex() < workbook.getNumberOfSheets()) {
            return workbook.getSheetAt(sheetId.getSheetIndex());
        }
        else {
            return workbook.getSheet(sheetId.getSheetName());
        }
    }

    /**
     * Try to get sheet by index and name.
     * If found a sheet by index, it's name will be overwritten by specified name,
     * if not, new sheet will be created with the name.
     *
     * @param workbook
     * @param sheetId
     * @return
     */
    public static Sheet getOrCreateSheet(Workbook workbook, SheetId sheetId) {
        if (sheetId == null) {
            throw new RuntimeException("Sheet id can not be null");
        }
        Sheet sheet = null;
        if (sheetId.getSheetIndex() == null || sheetId.getSheetIndex() >= workbook.getNumberOfSheets()) {
            if (StringUtils.isBlank(sheetId.getSheetName())) {
                if (sheetId.getSheetIndex() == null) {
                    throw new RuntimeException("Sheet id is not valid: " + sheetId);
                }
                else {
                    return workbook.createSheet(SheetId.DEFAULT_SHEET_NAME);
                }
            }
            else {
                return getOrCreateSheet(workbook, sheetId.getSheetName());
            }
        }
        else {
            sheet = workbook.getSheetAt(sheetId.getSheetIndex());
            if (sheet == null) {
                if (StringUtils.isBlank(sheetId.getSheetName())) {
                    return workbook.createSheet(); //
                }
                else {
                    return getOrCreateSheet(workbook, sheetId.getSheetName());
                }
            }
            else {
                if (StringUtils.isNotBlank(sheetId.getSheetName())) {
                    String safeSheetName = WorkbookUtil.createSafeSheetName(sheetId.getSheetName());
                    workbook.setSheetName(workbook.getSheetIndex(sheet), safeSheetName);
                }
                return sheet;
            }
        }
    }

    /**
     * Get sheet of workbook by name, create new if not exist.
     *
     * @param workbook
     * @param sheetName
     * @return
     */
    public static Sheet getOrCreateSheet(Workbook workbook, String sheetName) {
        String safeSheetName = WorkbookUtil.createSafeSheetName(sheetName);
        Sheet sheet = workbook.getSheet(safeSheetName);
        if (sheet == null) {
            return workbook.createSheet(safeSheetName);
        }
        else {
            return sheet;
        }
    }

    /**
     * Read from excel file stream to get the workbook, create a new one if not exists.
     *
     * @param templateFileStream
     * @param fileSuffix
     * @return
     * @throws IOException
     */
    public static Workbook initWorkbook(InputStream templateFileStream, String fileSuffix) throws IOException {
        if (SheetFileType.TYPE_XLS.equals(fileSuffix)) {
            return templateFileStream == null ? new HSSFWorkbook() : new HSSFWorkbook(templateFileStream);
        }
        else if (SheetFileType.TYPE_XLSX.equals(fileSuffix)) {
            return templateFileStream == null ? new XSSFWorkbook() : new XSSFWorkbook(templateFileStream);
        }
        else {
            throw new RuntimeException(String.format("%s file is not supported", fileSuffix));
        }
    }


    public static Cell getCell(Sheet sheet, Position position) {
        return getCell(sheet, position.getRow(), position.getColumn());
    }

    public static Cell getCell(Sheet sheet, int rowIdx, int colIdx) {
        return sheet.getRow(rowIdx).getCell(colIdx);
    }

    /**
     * Value from cell, the type of value will be determined automatically.
     *
     * @param cell
     * @return
     */
    public static Object getValueFromCell(Cell cell) {
        if (cell != null) {
            switch (cell.getCellType()) {
                case STRING:
                    return cell.getStringCellValue();
                case FORMULA:
                    switch (cell.getCachedFormulaResultType()) {
                        case NUMERIC:
                            return cell.getNumericCellValue();
                        case STRING:
                            return cell.getStringCellValue();
                        case BOOLEAN:
                            return cell.getBooleanCellValue();
                        default:
                            return cell.getCellFormula();
                    }
                case NUMERIC:
                    if (DateUtil.isCellDateFormatted(cell)) {
                        return cell.getDateCellValue();
                    }
                    else {
                        return cell.getNumericCellValue();
                    }
                case BLANK:
                    break;
                case BOOLEAN:
                    return cell.getBooleanCellValue();
                default:
                    return null;
            }
        }
        return null;
    }


    public static void setValueToCell(Cell cell, Object value) {
        if (ObjectUtils.allNotNull(cell, value)) {
            if (value instanceof String) {
                cell.setCellValue(String.valueOf(value));
            }
            else if (value instanceof Number) {
                cell.setCellValue(((Number) value).doubleValue());
            }
            else if (value instanceof Boolean) {
                cell.setCellValue((Boolean) value);
            }
            else if (value instanceof Date) {
                cell.setCellValue((Date) value);
            }
            else if (value instanceof LocalDateTime) {
                cell.setCellValue((LocalDateTime) value);
            }
            else if (value instanceof LocalDate) {
                cell.setCellValue((LocalDate) value);
            }
            else if (value instanceof Calendar) {
                cell.setCellValue(((Calendar) value).getTime());
            }
            else {
                cell.setCellValue(value.toString());
            }
        }
        else {
            System.out.printf("Cell or value is null: %s - %s%n", cell, value);
        }
    }

    /**
     * Write picture (in bytes) to a sheet in cells area (if specifically),
     * otherwise, the picture will be anchored to the start position cell and draws as is (actually be stretched somehow).
     *
     * @param sheet
     * @param startPos
     * @param endPosition  end position of area, not null.
     * @param pictureValue
     */
    public static void writePicture(Sheet sheet, Position startPos, Position endPosition, Picture pictureValue) {
        if (ObjectUtils.allNotNull(sheet, startPos, pictureValue)) {
            // System.out.printf("Write picture from %s to %s%n", startPos, endPosition);
            Workbook wb = sheet.getWorkbook();

            int pictureIdx = wb.addPicture(pictureValue.getData(), pictureValue.getPoiPictureType());

            CreationHelper helper = wb.getCreationHelper();
            Drawing drawing = sheet.createDrawingPatriarch();
            ClientAnchor anchor = helper.createClientAnchor();

            boolean isRestrictedInArea = endPosition != null && !endPosition.isUncertain();
            // System.out.printf("%s restrict in area%n", isRestrictedInArea ? "" : "not ");

            // set top-left corner of the picture,
            // subsequent call of Picture#resize() will operate relative to it
            anchor.setCol1(startPos.getColumn());
            anchor.setRow1(startPos.getRow());
            if (isRestrictedInArea) {
                anchor.setCol2(endPosition.getColumn() + 1); // exclusive
                anchor.setRow2(endPosition.getRow() + 1); // exclusive
            }
            anchor.setDx1(0);
            anchor.setDy1(0);
            anchor.setDx2(1023);
            anchor.setDy2(255);
            if (isRestrictedInArea) {
                anchor.setAnchorType(ClientAnchor.AnchorType.MOVE_AND_RESIZE); // dynamic size
            }
            else {
                anchor.setAnchorType(ClientAnchor.AnchorType.MOVE_DONT_RESIZE); // absolute size, should resize POI Picture.
            }
//            System.out.println(anchor);
            org.apache.poi.ss.usermodel.Picture pict = drawing.createPicture(anchor, pictureIdx);
            if (!isRestrictedInArea) {
                pict.resize();
            }
        }
        else {
            System.out.printf("Sheet or position or value is null: %s - %s - %s%n", sheet, startPos, pictureValue);
        }
    }

    /**
     * Copy style of area 'from' to area 'to' repeatedly.
     *
     * @param sheet
     * @param from  area copied from must has fixed size.
     * @param to    area copy to must has fixed size
     */
    public static void copyCells(Sheet sheet, Area from, Area to) {
        // collect all cells style
        Matrix mFrom = new Matrix<>(from.rowCount(), from.columnCount());
        List rowHeights = new ArrayList<>(from.rowCount());
        for (int i = 0; i < from.rowCount(); i++) {
            int rowIdx = from.getStartPosition().getRow() + i;
            Row row = sheet.getRow(rowIdx);
            if (row == null) {
                throw new RuntimeException(String.format("No row found at %d to copy from", rowIdx));
            }
            rowHeights.add(row.getHeightInPoints());
            for (int j = 0; j < from.columnCount(); j++) {
                int colIdx = from.getStartPosition().getColumn() + j;
                Cell cell = row.getCell(colIdx);
                if (cell == null) {
                    throw new RuntimeException(String.format("No cell found at (%d - %d) to copy from", rowIdx, colIdx));
                }
                mFrom.set(i, j, cell.getCellStyle());
            }
        }

        int rowMultiple = to.rowCount() / from.rowCount() + 1; //
        int colMultiple = to.columnCount() / from.columnCount() + 1;
        for (int x = 0; x < rowMultiple; x++) {
            for (int i = 0; i < from.rowCount(); i++) {
                int rowStep = x * from.rowCount();
                int newRowIdx = rowStep + i; // not global index
                if (newRowIdx >= to.rowCount()) {
                    continue;
                }
                Row copyRow = sheet.getRow(to.getStartPosition().getRow() + newRowIdx);
                if (copyRow == null) {
                    copyRow = sheet.createRow(to.getStartPosition().getRow() + newRowIdx);
                }
                copyRow.setHeightInPoints(rowHeights.get(i));
                for (int y = 0; y < colMultiple; y++) {
                    for (int j = 0; j < from.columnCount(); j++) {
                        int colStep = y * from.rowCount();
                        int newColIdx = colStep + j; // not global index
                        if (newColIdx >= to.columnCount()) {
                            continue;
                        }
                        Cell newCell = copyRow.createCell(to.getStartPosition().getColumn() + newColIdx);
                        CellStyle copiedStyle = mFrom.get(i, j);
                        CellStyle copyStyle = sheet.getWorkbook().createCellStyle();
                        copyStyle.cloneStyleFrom(copiedStyle);
                        newCell.setCellStyle(copyStyle);
                    }
                }
            }
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy