java - 我可以让我的数据提取程序(oracle数据库到excel)更加高效吗?

标签 java excel oracle jsp servlets

我目前正在使用 apache.poi 将数据从数据库提取到 Excel。我只是想看看是否可以加快提取过程。我的 JSP 中有一个选择值,要求提取 3500 行数据,这是唯一会极大减慢执行速度的情况。我正在从提取中创建两个单独的 Excel 文件。

第一类是简单的数据提取:

    private void createSiteFieldExcel(String workSheetName, List<String> columnHeader, List<MasterDataDto> masterDatatDtoList) {
    XSSFSheet sheet = masterDataWorkbook.createSheet(workSheetName);
    int cellNumber = 0;
    int rowNumber = 0;
    Row headerRow = sheet.createRow(rowNumber++);
    sheet.createFreezePane(0, 1);
    List<MasterDataDto> dataConsistencyList = new ArrayList<MasterDataDto>();
    for (Iterator<String> iterator = columnHeader.iterator(); iterator.hasNext();) {
        Cell cell = headerRow.createCell(cellNumber++);
        cell.setCellValue(iterator.next());
        // sets the header to be bold
        cell.setCellStyle(masterDataBoldStyle);
    }
    for (MasterDataDto masterDatatDto : masterDatatDtoList) {
        Row dataRow = sheet.createRow(rowNumber++);
        cellNumber = 0;

        Cell cell = dataRow.createCell(cellNumber++);
        cell.setCellValue(masterDatatDto.getDivision());

        cell = dataRow.createCell(cellNumber++);
        cell.setCellValue(masterDatatDto.getProject());

        cell = dataRow.createCell(cellNumber++);
        cell.setCellValue(masterDatatDto.getSiteName());

        if (columnHeader.size() == 4) {
            cell = dataRow.createCell(cellNumber++);
            cell.setCellValue(masterDatatDto.getField1());
            if (masterDatatDto.getField1() == null || masterDatatDto.getField1().trim().equals("")) {
                dataConsistencyList.add(masterDatatDto);
            }
        } else if (columnHeader.size() == 5) {
            cell = dataRow.createCell(cellNumber++);
            cell.setCellValue(masterDatatDto.getField1());

            cell = dataRow.createCell(cellNumber++);
            cell.setCellValue(masterDatatDto.getField2());

            if (masterDatatDto.getField2() == null || masterDatatDto.getField2().trim().equals("")) {
                dataConsistencyList.add(masterDatatDto);
            }

        }
        // Auto sizes column width
        for (int i = 0; i <= 5; i++)
            sheet.autoSizeColumn(i);
    }
    createConsistencyCheckFile(dataConsistencyList, columnHeader);
    // Auto sizes column width for data consistency excel
    for (int i = 0; i <= 9 ; i++)
        dataConsistencyWorksheet.autoSizeColumn(i);
        dataConsistencyWorksheet.createFreezePane(0, 1);

}

第二类是检查数据一致性(表明数据库中没有空白数据)

    private void createConsistencyCheckFile(List<MasterDataDto> dataConsistencyList, List<String> columnHeaders) {
    Cell cell = null;
    Row dataRow = null;
    int cellNumber = 0;
    dataRow = dataConsistencyWorksheet.createRow(dataConsistencyWorksheetRowNumber++);


    cell = dataRow.createCell(cellNumber++);
    cell.setCellValue(dataConsistencyWorksheetRowNumber - 1);


    cell = dataRow.createCell(cellNumber++);
    cell.setCellValue("SUMMARY");

    cell = dataRow.createCell(cellNumber++);
    cell.setCellValue(columnHeaders.size() - 1);

    cell = dataRow.createCell(cellNumber++);
    cell.setCellValue(dataConsistencyList.size());

    for (String columnHeader : columnHeaders) {
        cell = dataRow.createCell(cellNumber++);
        cell.setCellValue(columnHeader);
    }

    for (MasterDataDto masterDatatDto : dataConsistencyList) {

        cellNumber = 0;
        dataRow = dataConsistencyWorksheet.createRow(dataConsistencyWorksheetRowNumber++);

        cell = dataRow.createCell(cellNumber++);
        cell.setCellValue(dataConsistencyWorksheetRowNumber - 1);

        cell = dataRow.createCell(cellNumber++);
        cell.setCellValue("DETAIL");

        cell = dataRow.createCell(cellNumber++);
        cell.setCellValue(columnHeaders.size() - 1);

        cell = dataRow.createCell(cellNumber++);
        cell.setCellValue("N/A");

        cell = dataRow.createCell(cellNumber++);
        cell.setCellValue(masterDatatDto.getDivision());

        cell = dataRow.createCell(cellNumber++);
        cell.setCellValue(masterDatatDto.getProject());

        cell = dataRow.createCell(cellNumber++);
        cell.setCellValue(masterDatatDto.getSiteName());

        if (columnHeaders.size() == 4) {
            cell = dataRow.createCell(cellNumber++);
            cell.setCellValue("???");
        } else if (columnHeaders.size() == 5) {
            cell = dataRow.createCell(cellNumber++);
            cell.setCellValue(masterDatatDto.getField1());

            cell = dataRow.createCell(cellNumber++);
            cell.setCellValue("???");
        }

    }

}

本来我只上了第一个类,虽然需要时间来运行,但它确实完成了。由于我添加了数据一致性类部分,因此在创建第一个工作表后就会超时。

我最初使用 Apache POI,因为当我使用 JXL 时,它不允许我在一张纸上插入超过 65,500 条记录(行)。我有很多东西要提取。如果我需要提供更多程序以更清楚地了解我的问题,请告诉我。我衷心感谢您提前提供的帮助

我还有一个问题想补充一下。我正在考虑将数据库数据提取到 CSV 文件中,然后将 CSV 文件导入到 Excel 中。我的一个问题是,由于我最初是提取到工作簿中的多个工作表,有没有一种方法可以导出到多个 CSV 文件?那么如何从多个 CSV 文件中将它们添加到工作簿中的不同工作表中?

再次感谢 桑尼

你好,道格 这是我的查询代码:

    public List<MasterDataDto> getDFMasterData(int siteValueId, int firstColumnId, int secondColumnId, int divisionId) throws IOException, ClassNotFoundException, SQLException {
    List<MasterDataDto> masterDatatDtoList = new ArrayList<MasterDataDto>();
    Connection con = null;
    PreparedStatement ps = null;
    ResultSet rs = null;
    try {
        StringBuilder query = new StringBuilder();
        query.append("Select Distinct Dt.Name Division, Pr.Name Project, Addtl_Type.Name Site_Name, Atprt.Name col1, Atchd.Name col2");
        query.append(" From Addtl_Type_Rel Attr, Addtl_Type_Rel Attchd, Addtl_Type_Rel Attgrch, Addtl_Type  Atprt, Project Pr, Addtl_Type Atchd, Addtl_Type, Division_Type Dt");
        query.append(" Where Pr.Id = Attr.Parent_N_Value");
        query.append(" And Attr.Id = Attchd.Previous_Rel_Id");
        query.append(" And Pr.Division_Type = Dt.Id");
        query.append(" And Atchd.Id = Attgrch.Child_N_Value");
        query.append(" And Attgrch.Parent_Field_Id = Attchd.Child_Field_Id");
        query.append(" And Attchd.Id = Attgrch.Previous_Rel_Id");
        query.append(" And Attr.Child_Field_Id = Attchd.Parent_Field_Id");
        query.append(" And Atprt.Id = Attchd.Child_N_Value");
        query.append(" And Attchd.Parent_N_Value = Addtl_Type.Id");
        query.append(" And Attr.Parent_Field_Id = ?");
        query.append(" And Attr.Child_Field_Id = ?");
        query.append(" And Attchd.Child_Field_Id = ?");
        query.append(" And Attgrch.Child_Field_Id = ?");
        query.append(" And Dt.Id = ?");
        if (siteValueId != 0) {
            query.append(" And Attr.Child_N_Value = ?");
        }
        query.append(" Order By Project, Site_Name, col1, col2");

        con = getConnection();
        ps = con.prepareStatement(query.toString());
        ps.setInt(1, MasterDataConstants.PROJECT);
        ps.setInt(2, MasterDataConstants.SITE_NAME_ID);
        ps.setInt(3, firstColumnId);
        ps.setInt(4, secondColumnId);
        ps.setInt(5, divisionId);
        if (siteValueId != 0) {
            ps.setInt(6, siteValueId);
        }
        rs = ps.executeQuery();
        while (rs.next()) {
            MasterDataDto masterDataDto = new MasterDataDto();
            masterDataDto.setDivision(rs.getString("Division"));
            masterDataDto.setProject(rs.getString("Project"));
            masterDataDto.setSiteName(rs.getString("Site_Name"));
            masterDataDto.setField1(rs.getString("col1"));
            masterDataDto.setField2(rs.getString("col2"));
            System.out.println(masterDataDto.getDivision() + "\t" + masterDataDto.getProject() + "\t" + masterDataDto.getSiteName() + "\t" + masterDataDto.getField1() + "\t"
                    + masterDataDto.getField2());
            masterDatatDtoList.add(masterDataDto);
        }
    } finally {

        cleanUp(con, ps, rs);
    }
    return masterDatatDtoList;

如何才能提高效率? 谢谢 桑尼

大家好,我对该程序有一个新问题。我已经删除了 autoSizeColumn,它到达了即将写入 Excel 工作簿的位置。我现在收到 java.lang.OutOfMemoryError。 这是错误的完整堆栈跟踪: 异常

javax.servlet.ServletException:Servlet 执行抛出异常

根本原因

java.lang.OutOfMemoryError: GC overhead limit exceeded
org.apache.xmlbeans.impl.store.Saver$TextSaver.resize(Saver.java:1592)
org.apache.xmlbeans.impl.store.Saver$TextSaver.preEmit(Saver.java:1223)
org.apache.xmlbeans.impl.store.Saver$TextSaver.emit(Saver.java:1144)
org.apache.xmlbeans.impl.store.Saver$TextSaver.emitElement(Saver.java:926)
org.apache.xmlbeans.impl.store.Saver.processElement(Saver.java:456)
org.apache.xmlbeans.impl.store.Saver.process(Saver.java:307)
org.apache.xmlbeans.impl.store.Saver$TextSaver.saveToString(Saver.java:1727)
org.apache.xmlbeans.impl.store.Cursor._xmlText(Cursor.java:546)
org.apache.xmlbeans.impl.store.Cursor.xmlText(Cursor.java:2436)
org.apache.xmlbeans.impl.values.XmlObjectBase.xmlText(XmlObjectBase.java:1455)
org.apache.poi.xssf.model.SharedStringsTable.getKey(SharedStringsTable.java:130)
org.apache.poi.xssf.model.SharedStringsTable.addEntry(SharedStringsTable.java:176)
org.apache.poi.xssf.usermodel.XSSFCell.setCellValue(XSSFCell.java:350)
org.apache.poi.xssf.usermodel.XSSFCell.setCellValue(XSSFCell.java:320)
master.service.MasterDataService.createSiteFieldExcel(MasterDataService.java:1102)
master.service.MasterDataService.createMasterDataFile(MasterDataService.java:886)
master.service.MasterDataServlet.doGet(MasterDataServlet.java:22)
javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)

我必须在哪里增加 Eclipse 中的 JVM 大小。我正在运行 Tomcat,如果这也有帮助的话。 谢谢 桑尼

最佳答案

您可能会使用 Excel 的 JDBC 驱动程序,也许是 JDBC ODBC 桥,这需要一些 Windows 操作。 这将是最佳选择,因为您需要遍历数据库查询并可以立即将其写入 Excel“数据库”。

http://www.coderanch.com/t/465901/JDBC/databases/insert-data-excel-file-java

如果做不到这一点,请不要使用 DTO 列表,而是立即将每个 rs.next/DTO 添加到 Excel 工作表中。

关于java - 我可以让我的数据提取程序(oracle数据库到excel)更加高效吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24913918/

相关文章:

java - 使用固定值映射 JPA 中的枚举?

java - 根据接口(interface)信息创建列表

java - 如何将方法调用到要使用的公共(public)静态类中?

excel - 宏运行两次时内存不足

sql - java.lang.ClassCastException : com. mchange.v2.c3p0.impl.NewProxyConnection 问题

sql - NVL 功能

java - 为什么我的对象保持为空?

excel - Delphi - 将 ALT 键码传递给 Excel

python - 如何在python中比较两个列表列表,然后将数据写入excel

SQL : Oracle : Optimize LEFT Outer Join Query