jsp里使用java excel api实现文件下载

本文介绍如何使用JSP生成包含中文内容的Excel文件并解决文件名和内容的乱码问题。通过设置正确的编码和使用jxl库,实现了用户点击链接后直接下载中文名为“导出采购商明细报表Excel.xls”的Excel文件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    好久没有更新BLog内容了。主要是一直解决工作中遇到的一个问题,即需要把定单的产品项名细 生成一个excel文件,其实问题本身没有什么特别的技术要求,如果是生成word表格或许要采用专门的控件(顺便介绍一下,国内有个比较好的office系统控件,http://www.ntko.com/ 我试用过很好用,但需要花钱的),随便在网上搜一下就会有很多解决方案,我选择了jxl,主要是有清晰的示例代码。下载了类库和一个例子后,马上开始修改,添加,拷贝之类的工作(说实话,我主要是做维护工作的,偶尔有新的需求也是模仿已有的代码,改改即可,几乎没有什么创新内容,很惭愧在技术圈里混),原以为一天完成,结果三天才调试完,主要卡在乱码问题上,虽然现在已经通过,还是没有从根本上理解为什么,我是通过各种方式组合测试才找到答案。为了给有类似需求的网友提供借鉴,我把问题及解决思路整理出来,同时也是对自己加深印象。

   需求描述:
    用户点击OrderItemsToExcel.jsp后,直接弹出下载保存对话框,下载到本地保存。

  约束条件:
   只能用JSP实现并且不要调用java Bean,所有的代码都在jsp里完成,并且下载的文件名一定是中文名称。

  遇到的问题:
    1、 文件名乱码
    2、生成的excel文件中文内容乱码

   程序运行的环境:
      系统运行在weblogic5.1.0, jdk1.2.2, AIX 4.3.3,oracle817数据库

   因为是编码问题所以分析与编码有关的设置:
     数据库编码UTF-8
    JSP文件本身是UTF-8编码
    页面输出的charset也是UTF-8
    AIX的环境变量 LANG=Zh_CN

    在网上找了很多关于java系统的编码问题,也知道从jsp到页面显示过程中要涉及几个编码转换的过程,JSP----->java,java----->class,从数据库---java,从web服务器到浏览器,但是网上的一些方法不能用,因为我们使用的是JDK1.2.2, weblogic5.1 版本都很低,不支持新方法如:URLEncoder.encode() 只支持一个参数,不支持两个参数。现在想起来可能是网上的给出的解决方法太多把自己给搞乱了,看看我的原代码其实很简单,网上的东西只能作为参考,因为不同的运行环境可能会有不同的结果。比如说jsp参数pageEncoding不是所有的web服务器都支持的。

下面是代码,把数据库信息省略

 

<% @ page  extends = " tradeex.ec4.jsp.BaseJSPPage "   import = " java.util.*,java.text.*,java.sql.*,java.net.* "   import = " oracle.jdbc.driver.*,jxl.*,tradeex.ec4.util.* "  contentType = " text/html;charset=UTF8 " %>
<%
String sorefitem
= request.getParameter( " SOREFITEM " );
sorefitem 
=   " 24326 " ;
String sheetname 
=   " productsitems " ;
String excelsql 
=   " select oi.sorefitem,po.psuppliercompany suppliername,oi.pname productname,oi.ivendpartnumber productcode,oi.oqty quantity,oi.osellprice price,oi.pricecurrefitem currency,po.ponumber  "
                  
+ "  from ecorders.orderitems oi,ecorders.purchaseorders po  "
                  
+ "  where (oi.ostatus>3 or oi.ostatus=3 and oi.osubstatus=4) AND oi.sorefitem= " + sorefitem
                  
+ "  AND oi.sorefitem=po.sorefitem and oi.osellerid=po.psupplierid "  ;
int  col_num  =   0 ;

java.sql.Statement stm 
=   null ;
java.sql.ResultSet rs 
=   null ;
java.sql.Connection conn 
=   null ; try {
        Class.forName(
"oracle.jdbc.driver.OracleDriver");     
        }
catch  (ClassNotFoundException e) 
        
{ System.out.println ("no exist driver");
          System.exit(
0);
         }

       
try  
       
{    
            
            response.reset();
            response.setContentType(
"application/vnd.ms-excel;charset=UTF-8");
            response.setHeader(
"Content-Disposition" ,"attachment;filename="+new String("导出采购商明细报表Excel.xls".getBytes(),"iso-8859-1"));
                    
            OutputStream os 
= response.getOutputStream();//将 WritableWorkbook 写入到输出流
            jxl.write.WritableWorkbook wwb = jxl.Workbook.createWorkbook(os);    //创建Excel工作表    
            jxl.write.WritableSheet ws = wwb.createSheet("sheet_1",0);                       
            col_num 
= 7;            
            jxl.write.Label label_head;    
                            
            label_head 
= new jxl.write.Label(0,0,"请购单号");    
            ws.addCell(label_head);    
            label_head 
= new jxl.write.Label(1,0,"供应商名");    
            ws.addCell(label_head);    
            label_head 
= new jxl.write.Label(2,0,"产品规格型号");        
            ws.addCell(label_head);        
            label_head 
= new jxl.write.Label(3,0,"产品编码");        
            ws.addCell(label_head);        
            label_head 
= new jxl.write.Label(4,0,"数量");        
            ws.addCell(label_head);        
            label_head 
= new jxl.write.Label(5,0,"单价");    
            ws.addCell(label_head);        
            label_head 
= new jxl.write.Label(6,0,"定单号");
            ws.addCell(label_head);
//结果集中的数据添加到excel中
             
            jxl.write.Number label_num;        
            jxl.write.Label label_str;        
            jxl.write.WritableCellFormat floatFormat;            
            
int numrow = 1;
            System.out.println(System.currentTimeMillis()
+"  welcome to hehe!!!!!!!!!!!");
            
            conn 
= java.sql.DriverManager.getConnection("jdbc:oracle:thin:@192.168.1.180:1521:DB","system","manager");
            stm 
= conn.createStatement();    
            rs 
= stm.executeQuery(excelsql);
            
            
while(rs.next())        
            
{    
                System.out.println(System.currentTimeMillis()
+"   welcome to while!!!!!!!!!");           
                label_num 
= new jxl.write.Number(0,numrow,rs.getInt("sorefitem"));           
                ws.addCell(label_num);                        
                label_str 
= new jxl.write.Label(1,numrow,rs.getString("suppliername"));           
                ws.addCell(label_str);                      
                label_str 
= new jxl.write.Label(2,numrow,rs.getString("productname"));           
                ws.addCell(label_str);                      
                label_str 
= new jxl.write.Label(3,numrow,rs.getString("productcode"));           
                ws.addCell(label_str);                       
                floatFormat 
= new jxl.write.WritableCellFormat (jxl.write.NumberFormats.FLOAT);                
                label_num 
= new jxl.write.Number(4,numrow,rs.getDouble("quantity"),floatFormat);               
                ws.addCell(label_num);                  
                label_num 
= new jxl.write.Number(5,numrow,rs.getDouble("price"),floatFormat);          
                 ws.addCell(label_num);           
                 label_str 
= new jxl.write.Label(6,numrow,rs.getString("ponumber"));               
                 ws.addCell(label_str);                  
                 numrow 
++;    
             }
        
              wwb.write();
              wwb.close();
              os.flush();
              os.close();             
           }
 
           
catch (java.sql.SQLException sqle) {    
             System.out.println(
"sql error");             
             }
        
           
catch (Exception e) {
              System.out.println(
"catch error ------");        
             e.printStackTrace();    
           }
    
          
finally {
          System.out.println(System.currentTimeMillis()
+ "welcome to finally!!!!!!!");                    
           
if(stm != null)            
           
try{                
              stm.close();
           }
catch(Exception fe) { }            
           
if(conn != null)            
           
try{                
           conn.close();        
           }
            
           
catch(Exception fe2){ }        
           }

 
%>
JS JSP ASP .NET J2AM API接口和返回的版本 目前所有版本的JS JSP ASP .NET J2AM 都是提供源代码的,对于一些脚本语言来说,直接解压缩之后就可以使用了,不需要什么安装步骤。另外一些需要编译的语言,则提供了编译用的 shell 文件(Linux/Unix 下使用)和 bat 文件(Windows 下使用),或者直接提供编译好的二进制库文件。 不过为了让读者能够更清楚如何安装,我们还是对每种语言的安装都做详细的讲解,你可以在安装列表找到你感兴趣的语言的安装方法。 示例 如果你已经把 JS JSP ASP .NET J2AM 安装好了,那么接下来就让我们开始第一个小程序吧。按照惯例,第一个演示程序几乎总是 HelloWorld,我们也不想打破这个惯例,不过对于 PHPRPC 来说,有服务器端就要有客户端,否则我们就没有什么好演示的啦,所以我们的第一个演示程序实际上是两个,一个是服务器端,另一个是客户端。我们都先用 PHP 语言来写好了。 服务器端 view plaincopy to clipboardprint? <?php include ("php/phprpc_server.php"); function HelloWorld() { return 'Hello World!'; } $server = new PHPRPC_Server(); $server->add('HelloWorld'); $server->start(); ?> 客户端 view plaincopy to clipboardprint? <?php include ("php/phprpc_client.php"); $client = new PHPRPC_Client('http://127.0.0.1/server.php'); echo $client->HelloWorld(); ?> 对于服务器端程序,我们应该将它命名为 server.php(这是因为客户端调用时用的是这个名字,而不是 PHPRPC 的什么规定),然后把它放在本地 Web 服务器的根目录下,并保证服务器可以正常运行 PHP 程序,之后在浏览器或命令行下运行客户端程序,你就可以看到结果了。 这两个程序几乎简单到无需解释的地步,所以如果你已经明白它们的意思,那么就可以直接跳过下面的解释,继续看后面的例子。 服务器端第 1 句是将 它的服务器端程序包含到你的程序,之后的 2 - 4 句是定义一个远程调用的函数,你会发现它与本地函数没有任何区别。第 5 句是创建服务器端对象,第 6 句是添加要发布的方法,这添加的就是刚刚定义的 HelloWorld 函数,在 PHP 中,添加的发布方法是函数名的字符串表示,在其它语言中可能略有不同。第 7 句是启动服务。 客户端就更简单了,第 1 句是将 它的客户端程序包含到你的程序。第 2 句是创建客户端对象,其中的参数就是服务器端的地址。第 3 句是对远程方法(函数)的调用,之后通过 echo 将它显示出来。如果顺利的话,执行后你就会看到输出的 Hello World!。 上面的例子是发布的是函数,下面我们来看一下类中的静态方法如何发布: view plaincopy to clipboardprint? <?php include ("php/phprpc_server.php"); class Hello { static function HelloWorld() { return 'Hello World!'; } } $server = new PHPRPC_Server(); $server->add('HelloWorld', 'Hello'); $server->start(); ?> 这个服务器端只要它的名字与发布的地址与上面那个发布函数的例子一样的话,上面的那个客户端就可以得到同样的结果,也就是说,在客户端看来是没有任何区别的。 它并不是只可以在 PHP 中使用,它同样支持其它语言的服务器和客户端,而且还可以无差别的相互调用。 现在我们来看一下如何在 Java 中调用这个 PHP 的服务器方法: view plaincopy to clipboardprint? import org.phprpc.*; interface IHello { public String helloWorld(); } public class HelloWorld { public static void main ( String [] args ) { PHPRPC_Client client = new PHPRPC_Client("http://127.0.0.1/server.php"); IHello clientProxy = (IHello)client.useService(IHello.class); System.out.println(clientProxy.helloWorld()); } } 当我们把这个例子编译之后,在命令行中输入以下命令就可以看到执行结果了: java -classpath .;phprpc_client.jar HelloWorld 这个 Java 的客户端看上去比 PHP 的要稍微复杂一些,不过仍然很好理解。在 Java 客户端中,我们使用了接口来描述远程方法,之后我们通过 useService 方法返回一个远程代理对象,该对象实现了我们定义的接口,之后我们就可以直接调用远程方法 helloWorld 了。如果你比较细心的话,你还会发现我们在 PHP 中定义的方法和在 Java 中定义的接口的名字的大小写有点不同,但是仍然可以正常调用。是的,PHPRPC 发布的方法是不区分大小写的。所以不论你所使用的语言是否区分大小写,都可以按照自己(或语言)的习惯来定义方法名。 在本章的最后,我们再来看一下在 JavaScript 如何调用它的服务。顺便再强调一下,服务器端不止是可以用 PHP 来编写,你同样可以使用其它语言(比如 Java.NET,Ruby,Python 等),这我们只是以 PHP 为例而已。在这个例子中你还会看到如何使用加密传输。 view plaincopy to clipboardprint? <html> <head> <title>HelloWorld</title> [removed][removed] [removed] var client = new PHPRPC_Client('http://127.0.0.1/server.php', ['HelloWorld']); client.setEncryptMode(2); client.HelloWorld(function (result) { alert(result); }); [removed] </head> <body> </body> </html> 这个 JavaScript 是在网页中运行的,这建议大家要把 head 和 body 标签都写全,即使它们对你来说看上去没有什么用处,但是在有些浏览器中,如果这些标签没有写全,或者写的不正确,程序就不能正确运行。 在这个例子中,我们会发现在创建 PHPRPC_Client 对象时,除了要写服务器地址以外,还要将远程方法的名字作为参数,因为远程方法可能不止一个,所以这个参数是数组类型的。 client.setEncryptMode(2); 这句是设置加密传输,参数 2 表示双向加密,就是参数和结果都加密(只不过这个 HelloWorld 比较特殊,它没有参数)。 接下来就是调用远程方法 HelloWorld 了,我们会发现它跟 PHP 和 Java 客户端的调用不太一样。是的,在 JavaScript 中远程调用都是采用异步方式的,也就是说要获得结果,需要用回调函数,回调函数作为远程方法的最后一个参数,回调函数也有四个参数,这我们只使用第一个参数,也就是返回结果 result,通过 alert(result); 我们就可以在浏览器中看到最后弹出的 Hello World! 提示框了。 通过上面的例子,我们已经看到在 PHP、JavaJavaScript 这三种语言中使用 PHPRPC 都很简单,但因为语言的不同,在写法和用法上又有一些差别。不过你不用担心其它的语言跟它们也会有很大的差别,因为在接下来的章节中你很快就会发现其它语言跟这上面三种语言实现的写法和用法上的相似或相同之处了。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值