【问题标题】:Display Excel sheet in the Browser?在浏览器中显示 Excel 工作表?
【发布时间】:2011-03-31 11:37:01
【问题描述】:

我需要显示生成的excel(来自使用Apache POI的表)在网络浏览器中(不管是什么,Firefox,歌剧或 IE)。我用

创建了 JSP 文件

contentType="application/vnd.ms-excel"

但我不明白。

这是我的代码 sn-p:

<%@page session="true" contentType="application/vnd.ms-excel" pageEncoding="UTF-8"%>
<%@page import="org.apache.poi.ss.usermodel.CellStyle"%>
<%@page import="java.sql.DriverManager"%>
<%@page import="java.sql.ResultSet"%>
<%@page import="java.sql.Statement"%>
<%@page import="java.sql.Connection"%>
<%@page import="org.apache.poi.ss.usermodel.CreationHelper"%>
<%@page import="org.apache.poi.hssf.usermodel.HSSFCell"%>
<%@page import="org.apache.poi.hssf.usermodel.HSSFRow"%>
<%@page import="org.apache.poi.hssf.usermodel.HSSFWorkbook"%>
<%@page import="org.apache.poi.hssf.usermodel.HSSFSheet"%>

<html>
    <head>
        <%!
            int r=0;

            HSSFWorkbook book;
            HSSFSheet sheet;
            HSSFRow row;

            CreationHelper createHelper = book.getCreationHelper();

            Connection conn;
            Statement stmt;
            ResultSet rs;
        %>
        <title>Report</title>
        <%
            book = new HSSFWorkbook();
            sheet = book.createSheet("Report");
        %>
    </head>
    <body>
        <%
            try     {

                    // Header of the Excel File
                row = sheet.createRow(r);

                row.createCell(0).setCellValue("Visit ID");
                row.createCell(1).setCellValue("Carrier Name");
                row.createCell(2).setCellValue("Phone Number");
                row.createCell(3).setCellValue("Patient Name");
                row.createCell(4).setCellValue("Subscriber ID");
                row.createCell(5).setCellValue("Subscriber Name");
                row.createCell(6).setCellValue("Chart Number");
                row.createCell(7).setCellValue("Date Of Birth");
                row.createCell(8).setCellValue("Subscriber Employer");
                row.createCell(9).setCellValue("Service Date");
                row.createCell(10).setCellValue("Provider Name");
                row.createCell(11).setCellValue("CPT Code");
                row.createCell(12).setCellValue("Aging Date");
                row.createCell(13).setCellValue("Total");
                row.createCell(14).setCellValue("Follow Up Notes");
                row.createCell(15).setCellValue("Internal Status Code");

                CellStyle cellStyle = book.createCellStyle();
                cellStyle.setDataFormat(createHelper.createDataFormat().getFormat("MM/dd/yyyy"));

                Statement stNotes;
                ResultSet rsNotes;

                Class.forName("com.mysql.jdbc.Driver");

                conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/maintain", "root", "root");
                stmt = conn.createStatement();

                stNotes = conn.createStatement();

                rs = stmt.executeQuery("SELECT b.VisitID, b.CarrierName, b.PhoneNum, b.PatientName, "
                        + "b.SubscriberID, b.SubscriberName, b.ChartNum, b.DoB, b.SubscriberEmp, "
                        + "b.ServiceDate, b.ProviderName, b.CPTCode, b.BillingDate, b.BalanceAmt "
                        + "FROM billing b INNER JOIN followup f ON b.VisitID = f.VisitID GROUP BY VisitID");

                while(rs.next())    {
                    r++;

                    row = sheet.createRow(r);

                    row.createCell(0).setCellValue(rs.getString("VisitID"));
                    row.createCell(1).setCellValue(rs.getString("CarrierName"));
                    row.createCell(2).setCellValue(rs.getString("PhoneNum"));
                    row.createCell(3).setCellValue(rs.getString("PatientName"));
                    row.createCell(4).setCellValue(rs.getString("SubscriberID"));
                    row.createCell(5).setCellValue(rs.getString("SubscriberName"));
                    row.createCell(6).setCellValue(rs.getString("ChartNum"));
                    row.createCell(7).setCellValue(rs.getString("DoB"));
                    row.createCell(8).setCellValue(rs.getString("SubscriberEmp"));


                    row.createCell(9).setCellValue(rs.getString("ServiceDate"));
                    row.createCell(9).setCellStyle(cellStyle);

                    row.createCell(10).setCellValue(rs.getString("ProviderName"));
                    row.createCell(11).setCellValue(rs.getString("CPTCode"));

                    row.createCell(12).setCellValue(rs.getString("BillingDate"));
                    row.createCell(12).setCellStyle(cellStyle);

                    row.createCell(13).setCellValue(rs.getString("BalanceAmt"));

                    rsNotes = stNotes.executeQuery("SELECT Date, InternalStatusCode, FollowUpNote "
                            + "FROM followup WHERE VisitID='" + rs.getString("VisitID") + "' ORDER BY Date");

                    while(rsNotes.next())   {
                        row.createCell(14).setCellValue(rsNotes.getString("Date") + " - " + rsNotes.getString("FollowUpNote"));
                        row.createCell(15).setCellValue(rs.getString("VisitID"));
                    }
                }

            }
            catch(ClassNotFoundException cnf) {
                out.print("<br> Error : MySQL Driver not found. <br>");
            }
            catch(Exception ex)  {
                out.print("Error :  <br>" + ex);
            }
        %>
    </body>
</html>

我在 Tomcat 6.0.26 中遇到了这个异常:

exception

org.apache.jasper.JasperException: java.lang.NullPointerException
    org.apache.jasper.servlet.JspServletWrapper.getServlet(JspServletWrapper.java:156)
    org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:329)
    org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:313)
    org.apache.jasper.servlet.JspServlet.service(JspServlet.java:260)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:393)

root cause

java.lang.NullPointerException
    org.apache.jsp.GetReport_jsp.<init>(GetReport_jsp.java:29)
    sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
    sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
    java.lang.reflect.Constructor.newInstance(Constructor.java:513)
    java.lang.Class.newInstance0(Class.java:355)
    java.lang.Class.newInstance(Class.java:308)
    org.apache.jasper.servlet.JspServletWrapper.getServlet(JspServletWrapper.java:145)
    org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:329)
    org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:313)
    org.apache.jasper.servlet.JspServlet.service(JspServlet.java:260)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter(MonitorFilter.java:393)

我是否遗漏了什么或有什么不对? 谁能帮我解决这个问题?

提前感谢。

【问题讨论】:

  • @ammoQ - 我已经添加了兄弟.. 请检查一下..
  • 我现在看到您每次都为每个新问题编辑了问题。 你不应该这样做。它使答案毫无意义/无用。您应该为每个新的独立问题提出一个新问题!我已经回滚了原来的问题。您应该就新的IllegalStateException 问题提出一个新问题(或者只是阅读消息并进行逻辑思考......)。

标签: java excel jsp apache-poi


【解决方案1】:

您尝试这样做的方式没有任何意义。您不能像这样将 HTML 与 Excel 混合。最好创建一个 servlet 而不是 JSP 页面,让这个 servlet 只输出 Excel 文件而不输出其他文件。

类似这样的:

import java.io.*;    
import javax.servlet.http.*;
import javax.servlet.*;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
// ... plus all the other libs you need

public class ExcelServlet extends HttpServlet {
  public void doGet (HttpServletRequest req,
                     HttpServletResponse res)
    throws ServletException, IOException
  {
    HSSFWorkbook book;
    // ...
    // fill the book
    // ...
    res.setContentType("application/vnd.ms-excel");
    book.write(res.getOutputStream());
    res.getOutputStream().close();
  }
}

【讨论】:

  • 我已经按照你的建议做了。但是我得到 Error:
    java.lang.IllegalStateException: getWriter() has already been called for this response
    作为 excel 内容。你能澄清一下,为什么?
  • 您不能在同一个响应对象上同时调用 getWriter() 和 getOutputStream()。我猜JSP 页面隐含地调用getWriter(),这就是为什么你应该把它变成一个servlet。 (但不要相信我的话,我不是 JSP 专家)
【解决方案2】:
HSSFWorkbook book;
HSSFSheet sheet;
HSSFRow row;
CreationHelper createHelper = book.getCreationHelper();

您在初始化之前正在使用 book 对象。

【讨论】:

  • 我在那个 excel 文件中没有得到任何内容...你能找出原因吗?
  • @ven coder,您将工作簿写入文件的代码在哪里?您创建对象并向其添加数据,但您从未将其写入某处。从 POI Javadocs 看来,您需要致电 book.write(OutputStream)
【解决方案3】:

我建议不要这样做。

JSP 中的 Scriptlet 代码完全是错误的。

将数据库访问放在这样的页面中也不好。

更好的方法是 Spring MVC 及其 JExcelView。

【讨论】:

    【解决方案4】:

    这里有一个关于如何调试 JSP 异常的提示:

    在堆栈跟踪中,这个类

    java.lang.NullPointerException
    org.apache.jsp.GetReport_jsp.<init>(GetReport_jsp.java:29)
    

    是为您的 GetReport.jsp 生成的 java 类。您可以查看 $TOMCAT_HOME/work/&lt;enginename&gt;/&lt;hostname&gt;/&lt;appname&gt; 文件夹以查看生成的实际代码,并查看第 29 行的具体内容。

    【讨论】:

      【解决方案5】:

      看看 SourceForge 的 WorkbookTag 项目,它完全符合您的需求:使用 Apache POI 进行 HTML 工作表渲染...WorkbookTag

      【讨论】:

        猜你喜欢
        • 2012-02-12
        • 1970-01-01
        • 1970-01-01
        • 2021-03-01
        • 2017-03-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多