java - 如果行数超过 64k,如何使用 apache-poi 拆分 Excel 文件?

标签 java excel apache-poi

我正在使用下面的代码创建 Excel 文件

public class ResultSetToExcel {
        private HSSFWorkbook workbook;
        private HSSFSheet sheet;
        private HSSFFont boldFont;
        private HSSFDataFormat format;
        private ResultSet resultSet;
        private FormatType[] formatTypes;

        public ResultSetToExcel(ResultSet resultSet, FormatType[] formatTypes, String sheetName) {
            workbook = new HSSFWorkbook();
            this.resultSet = resultSet;
            sheet = workbook.createSheet(sheetName);
            boldFont = workbook.createFont();
            boldFont.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
            format = workbook.createDataFormat();
            this.formatTypes = formatTypes;
        }

        public ResultSetToExcel(ResultSet resultSet, String sheetName) {
            this(resultSet, null, sheetName);
        }

        private FormatType getFormatType(Class _class) {
            if (_class == Integer.class || _class == Long.class) {
                return FormatType.INTEGER;
            } else if (_class == Float.class || _class == Double.class) {
                return FormatType.FLOAT;
            } else if (_class == Timestamp.class || _class == java.sql.Date.class) {
                return FormatType.DATE;
            } else {
                return FormatType.TEXT;
            }
        }

        public void generate(OutputStream outputStream) throws Exception {
            try {
                ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
                if (formatTypes != null && formatTypes.length != resultSetMetaData.getColumnCount()) {
                    throw new IllegalStateException("Number of types is not identical to number of resultset columns. "
                            + "Number of types: " + formatTypes.length + ". Number of columns: "
                            + resultSetMetaData.getColumnCount());
                }
                int currentRow = 0;
                HSSFRow row = sheet.createRow(currentRow);
                int numCols = resultSetMetaData.getColumnCount();
                boolean isAutoDecideFormatTypes;
                if (isAutoDecideFormatTypes = (formatTypes == null)) {
                    formatTypes = new FormatType[numCols];
                }
                for (int i = 0; i < numCols; i++) {
                    String title = resultSetMetaData.getColumnName(i + 1);
                    writeCell(row, i, title, FormatType.TEXT, boldFont);
                    if (isAutoDecideFormatTypes) {
                        Class _class = Class.forName(resultSetMetaData.getColumnClassName(i + 1));
                        formatTypes[i] = getFormatType(_class);
                    }
                }

                currentRow++; // Write report rows
                while (resultSet.next()) {
                    row = sheet.createRow(currentRow++);
                    for (int i = 0; i < numCols; i++) {
                        Object value = resultSet.getObject(i + 1);
                        writeCell(row, i, value, formatTypes[i]);
                    }
                }
                // Autosize columns
                for (int i = 0; i < numCols; i++) {
                    sheet.autoSizeColumn((short) i);
                }
                workbook.write(outputStream);
            } finally {
                outputStream.close();
            }
        }

        public void generate(File file) throws Exception {
            generate(new FileOutputStream(file));
        }

        private void writeCell(HSSFRow row, int col, Object value, FormatType formatType) throws NestableException {
            writeCell(row, col, value, formatType, null, null);
        }

        private void writeCell(HSSFRow row, int col, Object value, FormatType formatType, HSSFFont font)
                throws NestableException {
            writeCell(row, col, value, formatType, null, font);
        }

        private void writeCell(HSSFRow row, int col, Object value, FormatType formatType, Short bgColor, HSSFFont font)
                throws NestableException {
            HSSFCell cell = HSSFCellUtil.createCell(row, col, null);
            if (value == null) {
                return;
            }
            if (font != null) {
                HSSFCellStyle style = workbook.createCellStyle();
                style.setFont(font);
                cell.setCellStyle(style);
            }
            switch (formatType) {
            case TEXT:
                cell.setCellValue(value.toString());
                break;
            case INTEGER:
                cell.setCellValue(((Number) value).intValue());
                HSSFCellUtil.setCellStyleProperty(cell, workbook, HSSFCellUtil.DATA_FORMAT, HSSFDataFormat
                        .getBuiltinFormat(("#,##0")));
                break;
            case FLOAT:
                cell.setCellValue(((Number) value).doubleValue());
                HSSFCellUtil.setCellStyleProperty(cell, workbook, HSSFCellUtil.DATA_FORMAT, HSSFDataFormat
                        .getBuiltinFormat(("#,##0.00")));

                break;
            case DATE:
                cell.setCellValue((Timestamp) value);
                HSSFCellUtil.setCellStyleProperty(cell, workbook, HSSFCellUtil.DATA_FORMAT, HSSFDataFormat
                        .getBuiltinFormat(("m/d/yy")));
                break;
            case MONEY:
                cell.setCellValue(((Number) value).intValue());
                HSSFCellUtil.setCellStyleProperty(cell, workbook, HSSFCellUtil.DATA_FORMAT, format
                        .getFormat("($#,##0.00);($#,##0.00)"));
                break;
            case PERCENTAGE:
                cell.setCellValue(((Number) value).doubleValue());
                HSSFCellUtil.setCellStyleProperty(cell, workbook, HSSFCellUtil.DATA_FORMAT, HSSFDataFormat
                        .getBuiltinFormat("0.00%"));
            }
            if (bgColor != null) {
                HSSFCellUtil.setCellStyleProperty(cell, workbook, HSSFCellUtil.FILL_FOREGROUND_COLOR, bgColor);
                HSSFCellUtil
                        .setCellStyleProperty(cell, workbook, HSSFCellUtil.FILL_PATTERN, HSSFCellStyle.SOLID_FOREGROUND);
            }
        }

        public enum FormatType {
            TEXT, INTEGER, FLOAT, DATE, MONEY, PERCENTAGE
        }
    }

以及实现上述代码的类

ResultSetToExcel resultSetToExcel = new ResultSetToExcel(rs,        new ResultSetToExcel.FormatType[] { ResultSetToExcel.FormatType.TEXT, ResultSetToExcel.FormatType.TEXT,            ResultSetToExcel.FormatType.INTEGER, ResultSetToExcel.FormatType.MONEY }, "Employee List");    resultSetToExcel.generate(new File("c:\\employees.xls"));

如果记录超过64000行,如何拆分Excel文件?

编辑:

如何获取 POI 中 Excel 工作表的行数? 如果是64k如何创建新的excel?

如何获取行数?

最佳答案

我建议您修改生成方法如下:

a) 确保它在一个电子表格中生成的行数不超过 64000 行。

b) 让它返回一个 boolean 值——如果 ResultSet 中没有更多行则返回 true,否则返回 false。

因此,生成方法中的主循环可能如下所示:

boolean allRowsDone = true;              
currentRow++; 
while (resultSet.next()) {
    row = sheet.createRow(currentRow++); 
    for (int i = 0; i < numCols; i++) { 
        Object value = resultSet.getObject(i + 1); 
        writeCell(row, i, value, formatTypes[i]); 
     }
     if (currentRow >= 64000) {
         allRowsDone = false;
         break; 
}
// put the rest of your code here
return allRowsDone;

然后,在调用程序中您可以执行如下操作:

String baseFile = "c:\\employees";
String fileName = baseFile + ".xls";
int fileCount = 1;
while (true) {
    boolean done = resultSetToExcel.generate(new File(fileName));
    if (done) break;
    fileName = baseFile + "_" + fileCount + ".xls";
    fileCount++;
}

这将导致您根据需要创建尽可能多的 Excel 文件,每个 Excel 文件包含不超过 64000 行。第一个文件名为“employees.xls”,第二个文件名为“employees_1.xls”,依此类推。

关于java - 如果行数超过 64k,如何使用 apache-poi 拆分 Excel 文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11204645/

相关文章:

java - pom.xml中自动递增版本号并显示在应用程序中

java - 如何使用字符串标记器和缓冲区。

java - 导入org.apache.poi.ooxml无法解析

java - 测试apache poi生成excel内容

java - if 条件中函数调用中的变量所做的更改是永久性的吗?

java - 使用 java 使用另一个 AD 中的用户在 AD 中进行搜索

vba - 如何在Excel VBA中将项目添加到表单中的组合框?

vba - 当我删除一系列单元格时(K2 :K18) getting an debug message

android - 如何在android程序中读取.xlsx文件

java - 如何在java中更改现有Excel(xlsx或xls)单元格的颜色