PJ,
 I am trying to use the copyRows as you suggested but I am hitting some
exceptions regarding formulas even though my data has no formulas. I took a
unit test of mine in which I was testing the bug I reported in
https://bz.apache.org/bugzilla/show_bug.cgi?id=69583 and refitted it with
an HSSFWorkbook along with my code which creates a new Workbook from each
Sheet of an existing Workbook. The unit code test is included as an
attachment. The stacktrace I get is:

[main] WARN org.apache.poi.POIDocument - DocumentSummaryInformation
property set came back as null
[main] WARN org.apache.poi.POIDocument - SummaryInformation property set
came back as null

java.lang.IllegalStateException: Cannot get a FORMULA value from a STRING
formula cell

at org.apache.poi.hssf.usermodel.HSSFCell.typeMismatch(HSSFCell.java:648)
at org.apache.poi.hssf.usermodel.HSSFCell.getCellFormula(HSSFCell.java:640)
at
org.apache.poi.hssf.usermodel.helpers.HSSFRowColShifter.updateRowFormulas(HSSFRowColShifter.java:74)
at
org.apache.poi.hssf.usermodel.helpers.HSSFRowShifter.updateRowFormulas(HSSFRowShifter.java:71)
at org.apache.poi.hssf.usermodel.HSSFRow.copyRowFrom(HSSFRow.java:853)
at
org.apache.nifi.excel.TestHSSFRowCopyRowFrom.test(TestHSSFRowCopyRowFrom.java:74)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)



On Mon, May 12, 2025 at 6:32 PM Dan S <dsti...@gmail.com> wrote:

> PJ,
> Thank you! That is very helpful and aligns very well with the XSSFSheet
> copyRows method in regards to use of CellCopyPolicy and CellCopyContext.
>
> On Mon, May 12, 2025 at 5:49 PM PJ Fanning <fannin...@apache.org> wrote:
>
>> There is copyRowFrom in HSSFRow.
>>
>>
>> https://poi.apache.org/apidocs/dev/org/apache/poi/hssf/usermodel/HSSFRow.html#copyRowFrom-org.apache.poi.ss.usermodel.Row-org.apache.poi.ss.usermodel.CellCopyPolicy-org.apache.poi.ss.usermodel.CellCopyContext-
>>
>> On Mon, 12 May 2025 at 21:54, Dan S <dsti...@gmail.com> wrote:
>> >
>> > XSSFSheet has a copyRows method which allows for copying the contents of
>> > one XSSFSheet to another one. I do not see an equivalent method for an
>> > HSSFSheet. I see from this post
>> > <
>> https://lists.apache.org/list?user@poi.apache.org:dfr=2020-1-1|dto=2025-5-12:HSSFSheet%20copy
>> <https://lists.apache.org/list?user@poi.apache.org:dfr=2020-1-1%7Cdto=2025-5-12:HSSFSheet%20copy>
>> >
>> > a solution which allows copying for HSSFSheet and XSSFSheet. I just
>> want to
>> > make sure if that is a recommended way for HSSF and if not has there
>> been
>> > any change to POI that provides methods for this?
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: user-unsubscr...@poi.apache.org
>> For additional commands, e-mail: user-h...@poi.apache.org
>>
>>
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellCopyContext;
import org.apache.poi.ss.usermodel.CellCopyPolicy;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.CreationHelper;
import org.apache.poi.ss.usermodel.DateUtil;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.junit.jupiter.api.Test;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.Iterator;

public class TestHSSFRowCopyRowFrom {
    @Test
    void test() throws IOException {
        CellCopyPolicy cellCopyPolicy = new CellCopyPolicy.Builder()
                .cellFormula(false) // NOTE: setting to false allows for copying the evaluated formula value.
                .cellStyle(CellCopyPolicy.DEFAULT_COPY_CELL_STYLE_POLICY)
                .cellValue(CellCopyPolicy.DEFAULT_COPY_CELL_VALUE_POLICY)
                .condenseRows(CellCopyPolicy.DEFAULT_CONDENSE_ROWS_POLICY)
                .copyHyperlink(CellCopyPolicy.DEFAULT_COPY_HYPERLINK_POLICY)
                .mergeHyperlink(CellCopyPolicy.DEFAULT_MERGE_HYPERLINK_POLICY)
                .mergedRegions(CellCopyPolicy.DEFAULT_COPY_MERGED_REGIONS_POLICY)
                .rowHeight(CellCopyPolicy.DEFAULT_COPY_ROW_HEIGHT_POLICY)
                .build();

        final LocalDateTime localDateTime = LocalDateTime.of(2023, 1, 1, 0, 0, 0);
        final LocalDateTime nonValidExcelDate = LocalDateTime.of(1899, 12, 31, 0, 0, 0);
        final Object[][] data = {
                {"transaction_id", "transaction_date", "transaction_time"},
                {75, localDateTime, nonValidExcelDate.plusHours(9).plusMinutes(53).plusSeconds(44).toLocalTime()},
                {78, localDateTime, nonValidExcelDate.plusHours(9).plusMinutes(55).plusSeconds(16).toLocalTime()}
        };

        final ByteArrayOutputStream workbookOutputStream = new ByteArrayOutputStream();
        try (Workbook workbook = new HSSFWorkbook()) {
            final Sheet sheet = workbook.createSheet("SomeSheetName");
            populateSheet(sheet, data);
            setCellStyles(sheet, workbook);
            workbook.write(workbookOutputStream);
        }

        try {
            final HSSFWorkbook originalWorkbook = new HSSFWorkbook(new ByteArrayInputStream(workbookOutputStream.toByteArray()));
            final Iterator<Sheet> originalSheetsIterator = originalWorkbook.sheetIterator();
            final CellCopyContext cellCopyContext = new CellCopyContext();

            int index = 0;
            while (originalSheetsIterator.hasNext()) {
                final HSSFSheet originalSheet = (HSSFSheet) originalSheetsIterator.next();
                final String originalSheetName = originalSheet.getSheetName();
                final Iterator<Row> originalRowsIterator = originalSheet.rowIterator();

                try (HSSFWorkbook newWorkbook = new HSSFWorkbook()) {
                    final HSSFSheet newSheet = newWorkbook.createSheet(originalSheetName);
                    while (originalRowsIterator.hasNext()) {
                        HSSFRow originalRow = (HSSFRow) originalRowsIterator.next();
                        HSSFRow newRow = newSheet.createRow(originalRow.getRowNum());
                        newRow.copyRowFrom(originalRow, cellCopyPolicy, cellCopyContext);
                    }

                    try (final OutputStream out = Files.newOutputStream(Paths.get(String.format("target/sheet-%s.xls", index)))) {
                        newWorkbook.write(out);
                    }
                }
                index++;
            }

        } catch (final IOException e) {
            throw new RuntimeException("Failed to split XLS file", e);
        }
    }

    private static void populateSheet(Sheet sheet, Object[][] data) {
        int rowCount = 0;
        for (Object[] dataRow : data) {
            Row row = sheet.createRow(rowCount++);
            int columnCount = 0;

            for (Object field : dataRow) {
                Cell cell = row.createCell(columnCount++);
                switch (field) {
                    case String string -> cell.setCellValue(string);
                    case Integer integer -> cell.setCellValue(integer.doubleValue());
                    case Long l -> cell.setCellValue(l.doubleValue());
                    case LocalDateTime localDateTime -> cell.setCellValue(localDateTime);
                    case LocalTime localTime -> cell.setCellValue(DateUtil.convertTime(DateTimeFormatter.ISO_LOCAL_TIME.format(localTime)));
                    default -> { }
                }
            }
        }
    }

    void setCellStyles(Sheet sheet, Workbook workbook) {
        CreationHelper creationHelper = workbook.getCreationHelper();
        CellStyle dayMonthYearCellStyle = workbook.createCellStyle();
        dayMonthYearCellStyle.setDataFormat(creationHelper.createDataFormat().getFormat("dd/mm/yyyy"));
        CellStyle hourMinuteSecond = workbook.createCellStyle();
        hourMinuteSecond.setDataFormat((short) 21); // 21 represents format h:mm:ss
        for (int rowNum = sheet.getFirstRowNum() + 1; rowNum < sheet.getLastRowNum() + 1; rowNum++) {
            Row row = sheet.getRow(rowNum);
            row.getCell(1).setCellStyle(dayMonthYearCellStyle);
            row.getCell(2).setCellStyle(hourMinuteSecond);
        }
    }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscr...@poi.apache.org
For additional commands, e-mail: user-h...@poi.apache.org

Reply via email to