精华内容
下载资源
问答
  • 使用jxls框架生成Excel,简单易懂。内含所使用的引用jar包版本。
  • 现在有个需求, 要求编写oracle存储过程生成Excel文件到指定目录, 但是oracle自己的API貌似不太给力, 所以只能通过另一种更强大的语言来实现了 ——Java。有一个Java框架叫POI,处理Excel起来非常好用,现在我把...

    现在有个需求,  要求编写oracle存储过程生成Excel文件到指定目录,  但是oracle自己的API貌似不太给力,  所以只能通过另一种更强大的语言来实现了  ——Java。有一个Java框架叫POI,处理Excel起来非常好用,现在我把过程记录下来:

    一、下载POI的jar包

    我的测试数据库的版本是11g, 所以下载的jar包不能太新,否则导入jar包的时候会报版本错误, 但又产生了一个问题,旧版本的jar包当然功能不是很全,包括我之前比较看重的给Excel加密的功能。之前为了这个功能试了很多版本,都不理想,只能放弃了,不知道oracle 12c版本会怎样,以后再试吧。。。

    步入正题,我们的jar包尽可能要新一些,那么,我们要先看看oracle 11g的Java版本:

    [oracle@centos6 bin]$ cd $ORACLE_HOME/jdk/bin/[oracle@centos6 bin]$ javac-version

    javac1.5.0_17

    e6277810b313ad339452f46b4f51812f.png

    javac的版本是1.5,那么导入的jar包不能是1.6及以上版本编译的。好吧,经过不懈努力,我下载了3.0.1版本的POI的jar包,

    a64af93c1e59589a1817622a9cd6845a.png

    POI的历史版本可以根据下面的链接下载:

    二、导入POI的jar包到数据库

    1.把jar包上传到服务器的一个目录,我这里是/java/目录:

    69d562bc75d008406390dfc1e0115758.png

    2.给用户授权:

    普通oracle用户要操作Java,必须通过sys授予JAVASYSPRIV权限:

    GRANT JAVASYSPRIV TO SCOTT;

    3.cd到上传目录,通过loadjava 命令导入oracle数据库:

    loadjava的基本语法:

    loadjava {-user | -u} username/password[@database]

    [option ...] filename [filename] ...

    具体选项请参考其他资料,这里不再赘述。

    我分别用如下命令导入:

    loadjava -r -f -o -user scott/tiger@cat poi-3.0.1-FINAL-20070705.jar

    bb5f844553fb12ec301c1c1e32013c14.png

    loadjava -r -f -o -user scott/tiger@cat poi-contrib-3.0.1-FINAL-20070705.jar

    59ab787e2d65903ead550f9b590e54af.png

    loadjava -r -f -o -user scott/tiger@cat poi-scratchpad-3.0.1-FINAL-20070705.jar

    33aac42c01b3829f885ed022cd336bad.png

    如图所示,这么老的版本导入的时候还是会报错,不过没有关系,报错的都是本例用不着的类,要是用现在最新版本的话,就没这么幸运了╮(╯▽╰)╭

    我们可以用SQL查询一下导入的情况:

    SELECT OBJECT_NAME,

    DBMS_JAVA.LONGNAME(OBJECT_NAME) JAVA_CLASS_NAME,

    O.STATUSFROMUSER_OBJECTS OWHERE OBJECT_TYPE LIKE 'JAVA CLASS';

    09a242321629f9ef0f932ad540164c64.png

    通过拼写SQL的方式,生成无效的类的删除语句:

    SELECT 'execute immediate''drop JAVA CLASS "' || OBJECT_NAME || '"'';'

    FROMUSER_OBJECTS OWHERE OBJECT_TYPE LIKE 'JAVA CLASS'

    AND O.STATUS <> 'VALID';

    把生成的语句执行,就删除了没用的而且无效的类了:

    BEGIN

    EXECUTE IMMEDIATE 'drop JAVA CLASS "/5e316ace_CommonsLogger"';EXECUTE IMMEDIATE 'drop JAVA CLASS "/eb16769d_HSSFCellUtil"';EXECUTE IMMEDIATE 'drop JAVA CLASS "/ff8d85a1_HSSFRegionUtil"';END;

    三、编写Java生成Excel程序,创建JAVA SOURCE

    在这里我写了一个通用的Java类,只要对方法传入SQL字符串和文件路径及名称组成的字符串这两个参数就可以完成功能,代码如下,并把它放到

    PL/SQL Developer中创建Java Source:

    create or replace and compile java source named createexcel asimportjava.io.FileNotFoundException;importjava.io.FileOutputStream;importjava.io.IOException;importjava.sql.Connection;importjava.sql.DriverManager;importjava.sql.ResultSet;importjava.sql.ResultSetMetaData;importjava.sql.SQLException;importjava.sql.Statement;importorg.apache.poi.hssf.usermodel.HSSFCell;importorg.apache.poi.hssf.usermodel.HSSFCellStyle;importorg.apache.poi.hssf.usermodel.HSSFFont;importorg.apache.poi.hssf.usermodel.HSSFRow;importorg.apache.poi.hssf.usermodel.HSSFSheet;importorg.apache.poi.hssf.usermodel.HSSFWorkbook;public classCreateExcel {private staticHSSFWorkbook wb;private staticHSSFSheet sheet;private static String connStr = "jdbc:oracle:thin:@192.168.*.*:1521:cat";private static String userStr = "scott";private static String pwdStr = "tiger";//@SuppressWarnings("deprecation")

    public static voidCreateExcel2003(String sql, String fileDir) {

    Connection conn= null;

    Statement stmt= null;

    ResultSet rs= null;int rowNum = 0;try{

    Class.forName("oracle.jdbc.OracleDriver");

    conn=DriverManager.getConnection(connStr, userStr, pwdStr);

    stmt=conn.createStatement();

    rs=stmt.executeQuery(sql);//创建题头

    if(rs.next()) {

    wb= newHSSFWorkbook();

    sheet= wb.createSheet("Result");//建立新的sheet对象//题头字体样式

    HSSFFont font =wb.createFont();

    font.setFontName("黑体");

    font.setFontHeightInPoints((short) 12);//设置字体大小

    font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);//粗体显示

    HSSFCellStyle cellStyle =wb.createCellStyle();

    cellStyle.setFont(font);

    HSSFRow row=sheet.createRow(rowNum);//获取列数和列名

    ResultSetMetaData rsMetaData =rs.getMetaData();int numberOfColumns =rsMetaData.getColumnCount();//System.out.println(numberOfColumns);

    HSSFCell[] cells = newHSSFCell[numberOfColumns];//根据列数获取列名题头

    for (int i = 0; i < numberOfColumns; i++) {

    cells[i]= row.createCell((short) i);

    cells[i].setCellValue(rsMetaData.getColumnName(i+1));

    cells[i].setCellStyle(cellStyle);

    }

    }//数据行样式

    HSSFCellStyle cellStyle1 =wb.createCellStyle();//创建数据行

    while(rs.next()){

    rowNum++;

    HSSFRow row= sheet.createRow(rowNum);//建立新行//获取列数

    ResultSetMetaData rsMetaData =rs.getMetaData();int numberOfColumns =rsMetaData.getColumnCount();

    HSSFCell[] cells= newHSSFCell[numberOfColumns];//获取数据

    for (int i = 0; i < numberOfColumns; i++) {

    cells[i]= row.createCell((short) i);

    cells[i].setCellValue(rs.getString(i+1));

    cells[i].setCellStyle(cellStyle1);//自动调整列宽

    sheet.autoSizeColumn((short) i);

    }//for (int i = 0; i < numberOfColumns; i++) {// //自动调整列宽//sheet.autoSizeColumn((short) i);//}

    }

    FileOutputStream fileOut= newFileOutputStream(fileDir);

    wb.write(fileOut);

    fileOut.close();

    }catch(SQLException e) {//TODO Auto-generated catch block

    e.printStackTrace();

    }catch(FileNotFoundException e) {//TODO Auto-generated catch block

    e.printStackTrace();

    }catch(IOException e) {//TODO Auto-generated catch block

    e.printStackTrace();

    }catch(ClassNotFoundException e) {//TODO Auto-generated catch block

    e.printStackTrace();

    }catch(Exception e) {//TODO Auto-generated catch block

    e.printStackTrace();

    }finally{if (rs != null) {try{

    rs.close();

    }catch(SQLException e) {

    e.printStackTrace();

    }

    rs= null;

    }if (stmt != null) {try{

    stmt.close();

    }catch(SQLException e) {

    e.printStackTrace();

    }

    stmt= null;

    }if (conn != null) {try{

    conn.close();

    }catch(SQLException e) {

    e.printStackTrace();

    }

    conn= null;

    }

    }

    }

    }

    四、创建调用Java代码的存储过程

    定义的存储过程开头是一样的,唯一不同的就是 “AS LANGUAGE ”后面的语法:

    {IS |AS} LANGUAGE JAVA

    NAME'method_fullname (java_type[, java_type]...)

    [return java_type]';

    我这里是:

    CREATE OR REPLACE PROCEDURE CREATE_EXCEL(P_SQL VARCHAR2, P_PATH VARCHAR2) ASLANGUAGE JAVA NAME'CreateExcel.CreateExcel2003(java.lang.String,java.lang.String)';

    第一个参数是SQL的字符串,第二个参数是文件路径+文件名称。

    这里需要注意一下,单引号里写的是”Java的类名全称.方法名(数据类型,...)”,区分大小写的。

    五、调用程序:

    输入相应参数:

    begin

    --Call the procedure

    create_excel(p_sql => 'select * from emp',

    p_path=> '/share/emp.xls');end;

    fbc15a75a6d5e042b79d78baad4d1dcb.png

    程序运行成功!

    看看文件目录:

    d28135c9b144df2702f0ce765cb59ee0.png

    文件已经生成,从服务器下载后,打开看看:

    2cbad55238fc146f160450cc429c5e65.png

    ok~~

    假如程序有错误,而且是Java代码的错误,我们怎样获取错误信息呢?这里只需要启用oracle的DBMS_JAVA.SET_OUTPUT();这个过程,

    此过程的语法是:

    PROCEDURE DBMS_JAVA.SET_OUTPUT(buffersize NUMBER);

    具体使用方法:

    SQL> SET serveroutput ON size 1000000;

    SQL> call dbms_java.set_output(1000000);

    如果Java代码有问题,我们就可以获得Java的打印信息,包括System.out.println();打印的信息:

    ce60148bf4fa4d0b4eb7074f30d2c451.png

    展开全文
  • 现在有个需求, 要求编写oracle存储过程生成Excel文件到指定目录, 但是oracle自己的API貌似不太给力, 所以只能通过另一种更强大的语言来实现了 ——Java。有一个Java框架叫POI,处理Excel起来非常好用,现在我...

    现在有个需求,  要求编写oracle存储过程生成Excel文件到指定目录,  但是oracle自己的API貌似不太给力,  所以只能通过另一种更强大的语言来实现了  ——Java。有一个Java框架叫POI,处理Excel起来非常好用,现在我把过程记录下来:

    一、下载POI的jar包

    我的测试数据库的版本是11g, 所以下载的jar包不能太新,否则导入jar包的时候会报版本错误, 但又产生了一个问题,旧版本的jar包当然功能不是很全,包括我之前比较看重的给Excel加密的功能。之前为了这个功能试了很多版本,都不理想,只能放弃了,不知道oracle 12c版本会怎样,以后再试吧。。。

    步入正题,我们的jar包尽可能要新一些,那么,我们要先看看oracle 11g的Java版本:

    [oracle@centos6 bin]$ cd $ORACLE_HOME/jdk/bin/
    [oracle@centos6 bin]$ javac -version
    javac 1.5.0_17

    javac的版本是1.5,那么导入的jar包不能是1.6及以上版本编译的。好吧,经过不懈努力,我下载了3.0.1版本的POI的jar包,

    POI的历史版本可以根据下面的链接下载:

    https://archive.apache.org/dist/poi/release/bin/

     

    二、导入POI的jar包到数据库

    1.把jar包上传到服务器的一个目录,我这里是/java/目录:

    2.给用户授权:

    普通oracle用户要操作Java,必须通过sys授予JAVASYSPRIV权限:

    GRANT JAVASYSPRIV TO SCOTT;

    3.cd到上传目录,通过loadjava 命令导入oracle数据库:

    loadjava的基本语法:

    loadjava {-user | -u} username/password[@database]
       [option ...] filename [filename] ...

    具体选项请参考其他资料,这里不再赘述。

    我分别用如下命令导入:

    loadjava -r -f -o -user scott/tiger@cat poi-3.0.1-FINAL-20070705.jar

    loadjava -r -f -o -user scott/tiger@cat poi-contrib-3.0.1-FINAL-20070705.jar

    loadjava -r -f -o -user scott/tiger@cat poi-scratchpad-3.0.1-FINAL-20070705.jar

    如图所示,这么老的版本导入的时候还是会报错,不过没有关系,报错的都是本例用不着的类,要是用现在最新版本的话,就没这么幸运了╮(╯▽╰)╭

    我们可以用SQL查询一下导入的情况:

    SELECT OBJECT_NAME,
           DBMS_JAVA.LONGNAME(OBJECT_NAME) JAVA_CLASS_NAME,
           O.STATUS
      FROM USER_OBJECTS O
     WHERE OBJECT_TYPE LIKE 'JAVA CLASS';

    通过拼写SQL的方式,生成无效的类的删除语句:

    SELECT 'execute immediate ''drop JAVA CLASS "' || OBJECT_NAME || '"'';'
      FROM USER_OBJECTS O
     WHERE OBJECT_TYPE LIKE 'JAVA CLASS'
       AND O.STATUS <> 'VALID';

    把生成的语句执行,就删除了没用的而且无效的类了:

    BEGIN
      EXECUTE IMMEDIATE 'drop JAVA CLASS "/5e316ace_CommonsLogger"';
      EXECUTE IMMEDIATE 'drop JAVA CLASS "/eb16769d_HSSFCellUtil"';
      EXECUTE IMMEDIATE 'drop JAVA CLASS "/ff8d85a1_HSSFRegionUtil"';
    END;

     

    三、编写Java生成Excel程序,创建JAVA SOURCE

    在这里我写了一个通用的Java类,只要对方法传入SQL字符串和文件路径及名称组成的字符串这两个参数就可以完成功能,代码如下,并把它放到

    PL/SQL Developer中创建Java Source:

    复制代码
    create or replace and compile java source named createexcel as
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.ResultSet;
    import java.sql.ResultSetMetaData;
    import java.sql.SQLException;
    import java.sql.Statement;
    
    import org.apache.poi.hssf.usermodel.HSSFCell;
    import org.apache.poi.hssf.usermodel.HSSFCellStyle;
    import org.apache.poi.hssf.usermodel.HSSFFont;
    import org.apache.poi.hssf.usermodel.HSSFRow;
    import org.apache.poi.hssf.usermodel.HSSFSheet;
    import org.apache.poi.hssf.usermodel.HSSFWorkbook;
    
    public class CreateExcel {
    
      private static HSSFWorkbook wb;
      private static HSSFSheet sheet;
      private static String connStr = "jdbc:oracle:thin:@192.168.*.*:1521:cat";
      private static String userStr = "scott";
      private static String pwdStr = "tiger";
    
      //@SuppressWarnings("deprecation")
      public static void CreateExcel2003(String sql, String fileDir) {
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;
        int rowNum = 0;
        
        try {
          Class.forName("oracle.jdbc.OracleDriver");
          conn = DriverManager.getConnection(connStr, userStr, pwdStr);
          stmt = conn.createStatement();
          rs = stmt.executeQuery(sql);
          
          //创建题头
          if (rs.next()) {
            wb = new HSSFWorkbook();
            sheet = wb.createSheet("Result");// 建立新的sheet对象
    
            // 题头字体样式
            HSSFFont font = wb.createFont();
            font.setFontName("黑体");
            font.setFontHeightInPoints((short) 12);// 设置字体大小
            font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);// 粗体显示
            HSSFCellStyle cellStyle = wb.createCellStyle();
            cellStyle.setFont(font);
            
            HSSFRow row = sheet.createRow(rowNum);
            // 获取列数和列名
            ResultSetMetaData rsMetaData = rs.getMetaData();
            int numberOfColumns = rsMetaData.getColumnCount();
            //System.out.println(numberOfColumns);
            HSSFCell[] cells = new HSSFCell[numberOfColumns];
            // 根据列数获取列名题头
            for (int i = 0; i < numberOfColumns; i++) {
              cells[i] = row.createCell((short) i);
              cells[i].setCellValue(rsMetaData.getColumnName(i+1));
              cells[i].setCellStyle(cellStyle);
            }
          }
          
          //数据行样式
          HSSFCellStyle cellStyle1 = wb.createCellStyle();
          
          //创建数据行
          while(rs.next()){
            rowNum ++;
            HSSFRow row = sheet.createRow(rowNum);// 建立新行
            // 获取列数
            ResultSetMetaData rsMetaData = rs.getMetaData();
            int numberOfColumns = rsMetaData.getColumnCount();
            HSSFCell[] cells = new HSSFCell[numberOfColumns];
            // 获取数据
            for (int i = 0; i < numberOfColumns; i++) {
              cells[i] = row.createCell((short) i);
              cells[i].setCellValue(rs.getString(i+1));
              cells[i].setCellStyle(cellStyle1);
              // 自动调整列宽
              sheet.autoSizeColumn((short) i);
            }
            
    //        for (int i = 0; i < numberOfColumns; i++) {
    //          // 自动调整列宽
    //          sheet.autoSizeColumn((short) i);
    //        }
          }
          
          FileOutputStream fileOut = new FileOutputStream(fileDir);
          wb.write(fileOut);
          fileOut.close();
          
        } catch (SQLException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
        } catch (FileNotFoundException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
        } catch (IOException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
        } catch (ClassNotFoundException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
        } catch (Exception e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
        } finally {
          if (rs != null) {
            try {
              rs.close();
            } catch (SQLException e) {
              e.printStackTrace();
            }
            rs = null;
          }
          if (stmt != null) {
            try {
              stmt.close();
            } catch (SQLException e) {
              e.printStackTrace();
            }
            stmt = null;
          }
          if (conn != null) {
            try {
              conn.close();
            } catch (SQLException e) {
              e.printStackTrace();
            }
            conn = null;
          }
        }
    
      }
    
    }
    复制代码

     

    四、创建调用Java代码的存储过程

    定义的存储过程开头是一样的,唯一不同的就是 “AS LANGUAGE ”后面的语法:

    {IS | AS} LANGUAGE JAVA
    NAME 'method_fullname (java_type[, java_type]...)
       [return java_type]';

     我这里是:

    CREATE OR REPLACE PROCEDURE CREATE_EXCEL(P_SQL VARCHAR2, P_PATH VARCHAR2) AS
      LANGUAGE JAVA NAME 'CreateExcel.CreateExcel2003(java.lang.String,java.lang.String)';

    第一个参数是SQL的字符串,第二个参数是文件路径+文件名称。

    这里需要注意一下,单引号里写的是”Java的类名全称.方法名(数据类型,...)”,区分大小写的。

     

    五、调用程序:

     输入相应参数:

    begin
      -- Call the procedure
      create_excel(p_sql => 'select * from emp',
                   p_path => '/share/emp.xls');
    end;

    程序运行成功!

    看看文件目录:

     文件已经生成,从服务器下载后,打开看看:

     ok~~

    假如程序有错误,而且是Java代码的错误,我们怎样获取错误信息呢?这里只需要启用oracle的DBMS_JAVA.SET_OUTPUT();这个过程,

    此过程的语法是:

    PROCEDURE DBMS_JAVA.SET_OUTPUT(buffersize NUMBER);

    具体使用方法:

    SQL> SET serveroutput ON size 1000000;
    SQL> call dbms_java.set_output(1000000);

    如果Java代码有问题,我们就可以获得Java的打印信息,包括System.out.println();打印的信息:

    展开全文
  • java批量生成Excel,并进行打包下载背景前端用form表单进行提交,就不写了,哈哈哈直接贴上java代码Excel工具类相关代码文件删除相关工具类Excel标题相关配置应用的框架是jeesite 背景 最近因为业务需求,要批量...

    背景

       最近因为业务需求,要批量下载EXCEL文件,并将文件压缩成zip包,再进行下载。所以写一写相关代码逻辑,以作笔记,
    

    前端用form表单进行提交,就不写了,哈哈哈

    直接贴上java代码

    controller层实现相关下载逻辑

    
        /**
         * 批量导出Excel
         *
         * @param
         * @return
         * @author douding
         * @date 2020/10/20 10:420
         */
        @RequestMapping(value = "downloadZip", method = RequestMethod.POST)
        public void downloadZip(BizPurchase bizPurchases, HttpServletResponse response, HttpServletRequest request,RedirectAttributes redirectAttributes) {
            try {
                String[] purchaseId = bizPurchases.getPurchaseIds();
                // 定义list用来存储生成的所有excel的文件路径
                List<String> tmpDir = new ArrayList<String>();
                //循环生成Excel文件,并将临时文件的路径保存下来
                for (int i = 0; i < purchaseId.length; i++) { 
                    // 从数据库查询相关数据
                    List<Student> list = studentDetailService.findListByParent(bizPurchase);
                    String date= DateUtils.getDate("yyyyMMddHHmmss");
                    // Excel文件相关内容
                    String fileName = name + ".xlsx";
                    // 临时文件名
                    // 生成的Excel文件名不能重复,因为用的文件名是时间命名的,防止出现重复所以加i
                    String fileName2 = name + i ;
                    //生成Excel文件的临时存放目录
                    String tmpDir1 = System.getProperty("java.io.tmpdir") + "\\" + fileName2 + ".xlsx"; // 临时目录tomcat7x64\temp
                    //将Excel文件目录保存起来,用于后面的打包下载
                    tmpDir.add(tmpDir1);
                    new ExportExcel(fileName, StudentDetail.class, 1).setDataList(list).writeFile(tmpDir1);
                }
                // 压缩文件名
                String data= DateUtils.getDate("yyyyMMddHHmmss");
                String fileName = "学生信息下载" + data+ ".zip";
                fileName = URLEncoder.encode(fileName, "UTF-8");
                response.setContentType("application/x-zip-compressed;charset=utf-8");
                response.setHeader("Content-disposition", String.format("attachment; filename=\"%s\"", fileName));
                // 添加所有采购单excel临时文件至压缩包
                ZipOutputStream zipOutputStream = null;
                zipOutputStream = new ZipOutputStream(response.getOutputStream());
                for (String tmpDir2 : tmpDir) {
                    ZipEntry zipEntry = new ZipEntry(new File(tmpDir2).getName());
                    InputStream input = null;
                    byte[] b = new byte[1024];
                    int len = 0;
                    // 判断文件是否为空,或文件目录是否存在
                    if (new File(tmpDir2).exists()) {
                        // excel流信息
                        input = new FileInputStream(new File(tmpDir2));
                        zipOutputStream.putNextEntry(zipEntry);
                        // 判断文件写入是否完成
                        while ((len = input.read(b)) != -1) {
                            zipOutputStream.write(b, 0, len);
                        }
                    }
                    input.close();
                    zipOutputStream.closeEntry();
                    FileUtils.deleteFile(tmpDir2);
                }
                zipOutputStream.close();
            } catch (Exception e) {
                addMessage(redirectAttributes, "导出采购详情失败!失败信息:" + e.getMessage());
            }
    
        }
    

    Excel工具类相关代码

    /**
     * Copyright &copy; 2012-2016 <a href="https://github.com/thinkgem/jeesite">JeeSite</a> All rights reserved.
     */
    package com.thinkgem.jeesite.common.utils.excel;
    
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.OutputStream;
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    import java.util.Collections;
    import java.util.Comparator;
    import java.util.Date;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    import javax.servlet.http.HttpServletResponse;
    
    import org.apache.commons.lang3.StringUtils;
    import org.apache.poi.ss.usermodel.Cell;
    import org.apache.poi.ss.usermodel.CellStyle;
    import org.apache.poi.ss.usermodel.Comment;
    import org.apache.poi.ss.usermodel.Font;
    import org.apache.poi.ss.usermodel.IndexedColors;
    import org.apache.poi.ss.usermodel.Row;
    import org.apache.poi.ss.usermodel.Sheet;
    import org.apache.poi.ss.usermodel.Workbook;
    import org.apache.poi.ss.util.CellRangeAddress;
    import org.apache.poi.xssf.streaming.SXSSFWorkbook;
    import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
    import org.apache.poi.xssf.usermodel.XSSFRichTextString;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import com.google.common.collect.Lists;
    import com.thinkgem.jeesite.common.utils.Encodes;
    import com.thinkgem.jeesite.common.utils.Reflections;
    import com.thinkgem.jeesite.common.utils.excel.annotation.ExcelField;
    import com.thinkgem.jeesite.modules.sys.utils.DictUtils;
    
    /**
     * 导出Excel文件(导出“XLSX”格式,支持大数据量导出   @see org.apache.poi.ss.SpreadsheetVersion)
     * @author ThinkGem
     * @version 2013-04-21
     */
    public class ExportExcel {
    	
    	private static Logger log = LoggerFactory.getLogger(ExportExcel.class);
    			
    	/**
    	 * 工作薄对象
    	 */
    	private SXSSFWorkbook wb;
    	
    	/**
    	 * 工作表对象
    	 */
    	private Sheet sheet;
    	
    	/**
    	 * 样式列表
    	 */
    	private Map<String, CellStyle> styles;
    	
    	/**
    	 * 当前行号
    	 */
    	private int rownum;
    	
    	/**
    	 * 注解列表(Object[]{ ExcelField, Field/Method })
    	 */
    	List<Object[]> annotationList = Lists.newArrayList();
    	
    	/**
    	 * 构造函数
    	 * @param title 表格标题,传“空值”,表示无标题
    	 * @param cls 实体对象,通过annotation.ExportField获取标题
    	 */
    	public ExportExcel(String title, Class<?> cls){
    		this(title, cls, 1);
    	}
    	
    	/**
    	 * 构造函数
    	 * @param title 表格标题,传“空值”,表示无标题
    	 * @param cls 实体对象,通过annotation.ExportField获取标题
    	 * @param type 导出类型(1:导出数据;2:导出模板)
    	 * @param groups 导入分组
    	 */
    	public ExportExcel(String title, Class<?> cls, int type, int... groups){
    		// Get annotation field 
    		Field[] fs = cls.getDeclaredFields();
    		for (Field f : fs){
    			ExcelField ef = f.getAnnotation(ExcelField.class);
    			if (ef != null && (ef.type()==0 || ef.type()==type)){
    				if (groups!=null && groups.length>0){
    					boolean inGroup = false;
    					for (int g : groups){
    						if (inGroup){
    							break;
    						}
    						for (int efg : ef.groups()){
    							if (g == efg){
    								inGroup = true;
    								annotationList.add(new Object[]{ef, f});
    								break;
    							}
    						}
    					}
    				}else{
    					annotationList.add(new Object[]{ef, f});
    				}
    			}
    		}
    		// Get annotation method
    		Method[] ms = cls.getDeclaredMethods();
    		for (Method m : ms){
    			ExcelField ef = m.getAnnotation(ExcelField.class);
    			if (ef != null && (ef.type()==0 || ef.type()==type)){
    				if (groups!=null && groups.length>0){
    					boolean inGroup = false;
    					for (int g : groups){
    						if (inGroup){
    							break;
    						}
    						for (int efg : ef.groups()){
    							if (g == efg){
    								inGroup = true;
    								annotationList.add(new Object[]{ef, m});
    								break;
    							}
    						}
    					}
    				}else{
    					annotationList.add(new Object[]{ef, m});
    				}
    			}
    		}
    		// Field sorting
    		Collections.sort(annotationList, new Comparator<Object[]>() {
    			public int compare(Object[] o1, Object[] o2) {
    				return new Integer(((ExcelField)o1[0]).sort()).compareTo(
    						new Integer(((ExcelField)o2[0]).sort()));
    			};
    		});
    		// Initialize
    		List<String> headerList = Lists.newArrayList();
    		for (Object[] os : annotationList){
    			String t = ((ExcelField)os[0]).title();
    			// 如果是导出,则去掉注释
    			if (type==1){
    				String[] ss = StringUtils.split(t, "**", 2);
    				if (ss.length==2){
    					t = ss[0];
    				}
    			}
    			headerList.add(t);
    		}
    		initialize(title, headerList);
    	}
    	
    	/**
    	 * 构造函数
    	 * @param title 表格标题,传“空值”,表示无标题
    	 * @param headers 表头数组
    	 */
    	public ExportExcel(String title, String[] headers) {
    		initialize(title, Lists.newArrayList(headers));
    	}
    	
    	/**
    	 * 构造函数
    	 * @param title 表格标题,传“空值”,表示无标题
    	 * @param headerList 表头列表
    	 */
    	public ExportExcel(String title, List<String> headerList) {
    		initialize(title, headerList);
    	}
    	
    	/**
    	 * 初始化函数
    	 * @param title 表格标题,传“空值”,表示无标题
    	 * @param headerList 表头列表
    	 */
    	private void initialize(String title, List<String> headerList) {
    		this.wb = new SXSSFWorkbook(500);
    		this.sheet = wb.createSheet("Export");
    		this.styles = createStyles(wb);
    		// Create title
    		if (StringUtils.isNotBlank(title)){
    			Row titleRow = sheet.createRow(rownum++);
    			titleRow.setHeightInPoints(30);
    			Cell titleCell = titleRow.createCell(0);
    			titleCell.setCellStyle(styles.get("title"));
    			titleCell.setCellValue(title);
    			sheet.addMergedRegion(new CellRangeAddress(titleRow.getRowNum(),
    					titleRow.getRowNum(), titleRow.getRowNum(), headerList.size()-1));
    		}
    		// Create header
    		if (headerList == null){
    			throw new RuntimeException("headerList not null!");
    		}
    		Row headerRow = sheet.createRow(rownum++);
    		headerRow.setHeightInPoints(16);
    		for (int i = 0; i < headerList.size(); i++) {
    			Cell cell = headerRow.createCell(i);
    			cell.setCellStyle(styles.get("header"));
    			String[] ss = StringUtils.split(headerList.get(i), "**", 2);
    			if (ss.length==2){
    				cell.setCellValue(ss[0]);
    				Comment comment = this.sheet.createDrawingPatriarch().createCellComment(
    						new XSSFClientAnchor(0, 0, 0, 0, (short) 3, 3, (short) 5, 6));
    				comment.setString(new XSSFRichTextString(ss[1]));
    				cell.setCellComment(comment);
    			}else{
    				cell.setCellValue(headerList.get(i));
    			}
    			sheet.autoSizeColumn(i);
    		}
    		for (int i = 0; i < headerList.size(); i++) {  
    			int colWidth = sheet.getColumnWidth(i)*2;
    	        sheet.setColumnWidth(i, colWidth < 3000 ? 3000 : colWidth);  
    		}
    		log.debug("Initialize success.");
    	}
    	
    	/**
    	 * 创建表格样式
    	 * @param wb 工作薄对象
    	 * @return 样式列表
    	 */
    	private Map<String, CellStyle> createStyles(Workbook wb) {
    		Map<String, CellStyle> styles = new HashMap<String, CellStyle>();
    		
    		CellStyle style = wb.createCellStyle();
    		style.setAlignment(CellStyle.ALIGN_CENTER);
    		style.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
    		Font titleFont = wb.createFont();
    		titleFont.setFontName("Arial");
    		titleFont.setFontHeightInPoints((short) 16);
    		titleFont.setBoldweight(Font.BOLDWEIGHT_BOLD);
    		style.setFont(titleFont);
    		styles.put("title", style);
    
    		style = wb.createCellStyle();
    		style.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
    		style.setBorderRight(CellStyle.BORDER_THIN);
    		style.setRightBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
    		style.setBorderLeft(CellStyle.BORDER_THIN);
    		style.setLeftBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
    		style.setBorderTop(CellStyle.BORDER_THIN);
    		style.setTopBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
    		style.setBorderBottom(CellStyle.BORDER_THIN);
    		style.setBottomBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
    		Font dataFont = wb.createFont();
    		dataFont.setFontName("Arial");
    		dataFont.setFontHeightInPoints((short) 10);
    		style.setFont(dataFont);
    		styles.put("data", style);
    		
    		style = wb.createCellStyle();
    		style.cloneStyleFrom(styles.get("data"));
    		style.setAlignment(CellStyle.ALIGN_LEFT);
    		styles.put("data1", style);
    
    		style = wb.createCellStyle();
    		style.cloneStyleFrom(styles.get("data"));
    		style.setAlignment(CellStyle.ALIGN_CENTER);
    		styles.put("data2", style);
    
    		style = wb.createCellStyle();
    		style.cloneStyleFrom(styles.get("data"));
    		style.setAlignment(CellStyle.ALIGN_RIGHT);
    		styles.put("data3", style);
    		
    		style = wb.createCellStyle();
    		style.cloneStyleFrom(styles.get("data"));
    //		style.setWrapText(true);
    		style.setAlignment(CellStyle.ALIGN_CENTER);
    		style.setFillForegroundColor(IndexedColors.GREY_50_PERCENT.getIndex());
    		style.setFillPattern(CellStyle.SOLID_FOREGROUND);
    		Font headerFont = wb.createFont();
    		headerFont.setFontName("Arial");
    		headerFont.setFontHeightInPoints((short) 10);
    		headerFont.setBoldweight(Font.BOLDWEIGHT_BOLD);
    		headerFont.setColor(IndexedColors.WHITE.getIndex());
    		style.setFont(headerFont);
    		styles.put("header", style);
    		
    		return styles;
    	}
    
    	/**
    	 * 添加一行
    	 * @return 行对象
    	 */
    	public Row addRow(){
    		return sheet.createRow(rownum++);
    	}
    	
    
    	/**
    	 * 添加一个单元格
    	 * @param row 添加的行
    	 * @param column 添加列号
    	 * @param val 添加值
    	 * @return 单元格对象
    	 */
    	public Cell addCell(Row row, int column, Object val){
    		return this.addCell(row, column, val, 0, Class.class);
    	}
    	
    	/**
    	 * 添加一个单元格
    	 * @param row 添加的行
    	 * @param column 添加列号
    	 * @param val 添加值
    	 * @param align 对齐方式(1:靠左;2:居中;3:靠右)
    	 * @return 单元格对象
    	 */
    	public Cell addCell(Row row, int column, Object val, int align, Class<?> fieldType){
    		Cell cell = row.createCell(column);
    		String cellFormatString = "@";
    		try {
    			if(val == null){
    				cell.setCellValue("");
    			}else if(fieldType != Class.class){
    				cell.setCellValue((String)fieldType.getMethod("setValue", Object.class).invoke(null, val));
    			}else{
    				if(val instanceof String) {
    					cell.setCellValue((String) val);
    				}else if(val instanceof Integer) {
    					cell.setCellValue((Integer) val);
    					cellFormatString = "0";
    				}else if(val instanceof Long) {
    					cell.setCellValue((Long) val);
    					cellFormatString = "0";
    				}else if(val instanceof Double) {
    					cell.setCellValue((Double) val);
    					cellFormatString = "0.00";
    				}else if(val instanceof Float) {
    					cell.setCellValue((Float) val);
    					cellFormatString = "0.00";
    				}else if(val instanceof Date) {
    					cell.setCellValue((Date) val);
    					cellFormatString = "yyyy-MM-dd HH:mm";
    				}else {
    					cell.setCellValue((String)Class.forName(this.getClass().getName().replaceAll(this.getClass().getSimpleName(), 
    						"fieldtype."+val.getClass().getSimpleName()+"Type")).getMethod("setValue", Object.class).invoke(null, val));
    				}
    			}
    			if (val != null){
    				CellStyle style = styles.get("data_column_"+column);
    				if (style == null){
    					style = wb.createCellStyle();
    					style.cloneStyleFrom(styles.get("data"+(align>=1&&align<=3?align:"")));
    			        style.setDataFormat(wb.createDataFormat().getFormat(cellFormatString));
    					styles.put("data_column_" + column, style);
    				}
    				cell.setCellStyle(style);
    			}
    		} catch (Exception ex) {
    			log.info("Set cell value ["+row.getRowNum()+","+column+"] error: " + ex.toString());
    			cell.setCellValue(val.toString());
    		}
    		return cell;
    	}
    
    	/**
    	 * 添加数据(通过annotation.ExportField添加数据)
    	 * @return list 数据列表
    	 */
    	public <E> ExportExcel setDataList(List<E> list){
    		for (E e : list){
    			int colunm = 0;
    			Row row = this.addRow();
    			StringBuilder sb = new StringBuilder();
    			for (Object[] os : annotationList){
    				ExcelField ef = (ExcelField)os[0];
    				Object val = null;
    				// Get entity value
    				try{
    					if (StringUtils.isNotBlank(ef.value())){
    						val = Reflections.invokeGetter(e, ef.value());
    					}else{
    						if (os[1] instanceof Field){
    							val = Reflections.invokeGetter(e, ((Field)os[1]).getName());
    						}else if (os[1] instanceof Method){
    							val = Reflections.invokeMethod(e, ((Method)os[1]).getName(), new Class[] {}, new Object[] {});
    						}
    					}
    					// If is dict, get dict label
    					if (StringUtils.isNotBlank(ef.dictType())){
    						val = DictUtils.getDictLabel(val==null?"":val.toString(), ef.dictType(), "");
    					}
    				}catch(Exception ex) {
    					// Failure to ignore
    					log.info(ex.toString());
    					val = "";
    				}
    				this.addCell(row, colunm++, val, ef.align(), ef.fieldType());
    				sb.append(val + ", ");
    			}
    			log.debug("Write success: ["+row.getRowNum()+"] "+sb.toString());
    		}
    		return this;
    	}
    	
    	/**
    	 * 输出数据流
    	 * @param os 输出数据流
    	 */
    	public ExportExcel write(OutputStream os) throws IOException{
    		wb.write(os);
    		return this;
    	}
    	
    	/**
    	 * 输出到客户端
    	 * @param fileName 输出文件名
    	 */
    	public ExportExcel write(HttpServletResponse response, String fileName) throws IOException{
    		response.reset();
            response.setContentType("application/octet-stream; charset=utf-8");
            response.setHeader("Content-Disposition", "attachment; filename="+Encodes.urlEncode(fileName));
    		write(response.getOutputStream());
    		return this;
    	}
    	
    	/**
    	 * 输出到文件
    	 * @param fileName 输出文件名
    	 */
    	public ExportExcel writeFile(String name) throws FileNotFoundException, IOException{
    		FileOutputStream os = new FileOutputStream(name);
    		this.write(os);
    		return this;
    	}
    	
    	/**
    	 * 清理临时文件
    	 */
    	public ExportExcel dispose(){
    		wb.dispose();
    		return this;
    	}
    	
    //	/**
    //	 * 导出测试
    //	 */
    //	public static void main(String[] args) throws Throwable {
    //		
    //		List<String> headerList = Lists.newArrayList();
    //		for (int i = 1; i <= 10; i++) {
    //			headerList.add("表头"+i);
    //		}
    //		
    //		List<String> dataRowList = Lists.newArrayList();
    //		for (int i = 1; i <= headerList.size(); i++) {
    //			dataRowList.add("数据"+i);
    //		}
    //		
    //		List<List<String>> dataList = Lists.newArrayList();
    //		for (int i = 1; i <=1000000; i++) {
    //			dataList.add(dataRowList);
    //		}
    //
    //		ExportExcel ee = new ExportExcel("表格标题", headerList);
    //		
    //		for (int i = 0; i < dataList.size(); i++) {
    //			Row row = ee.addRow();
    //			for (int j = 0; j < dataList.get(i).size(); j++) {
    //				ee.addCell(row, j, dataList.get(i).get(j));
    //			}
    //		}
    //		
    //		ee.writeFile("target/export.xlsx");
    //
    //		ee.dispose();
    //		
    //		log.debug("Export success.");
    //		
    //	}
    
    }
    
    

    文件删除相关工具类

    /**
     * Copyright &copy; 2012-2016 <a href="https://github.com/thinkgem/jeesite">JeeSite</a> All rights reserved.
     */
    package com.thinkgem.jeesite.common.utils;
    
    import java.io.BufferedOutputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.io.RandomAccessFile;
    import java.util.Enumeration;
    import java.util.List;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.apache.tools.zip.ZipEntry;
    import org.apache.tools.zip.ZipFile;
    import org.apache.tools.zip.ZipOutputStream;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import com.google.common.collect.Lists;
    
    /**
     * 文件操作工具类
     * 实现文件的创建、删除、复制、压缩、解压以及目录的创建、删除、复制、压缩解压等功能
     * @author ThinkGem
     * @version 2015-3-16
     */
    public class FileUtils extends org.apache.commons.io.FileUtils {
    	
    	private static Logger logger = LoggerFactory.getLogger(FileUtils.class);
    
    	/**
    	 * 复制单个文件,如果目标文件存在,则不覆盖
    	 * @param srcFileName 待复制的文件名
    	 * @param descFileName 目标文件名
    	 * @return 如果复制成功,则返回true,否则返回false
    	 */
    	public static boolean copyFile(String srcFileName, String descFileName) {
    		return FileUtils.copyFileCover(srcFileName, descFileName, false);
    	}
    
    	/**
    	 * 复制单个文件
    	 * @param srcFileName 待复制的文件名
    	 * @param descFileName 目标文件名
    	 * @param coverlay 如果目标文件已存在,是否覆盖
    	 * @return 如果复制成功,则返回true,否则返回false
    	 */
    	public static boolean copyFileCover(String srcFileName,
    			String descFileName, boolean coverlay) {
    		File srcFile = new File(srcFileName);
    		// 判断源文件是否存在
    		if (!srcFile.exists()) {
    			logger.debug("复制文件失败,源文件 " + srcFileName + " 不存在!");
    			return false;
    		}
    		// 判断源文件是否是合法的文件
    		else if (!srcFile.isFile()) {
    			logger.debug("复制文件失败," + srcFileName + " 不是一个文件!");
    			return false;
    		}
    		File descFile = new File(descFileName);
    		// 判断目标文件是否存在
    		if (descFile.exists()) {
    			// 如果目标文件存在,并且允许覆盖
    			if (coverlay) {
    				logger.debug("目标文件已存在,准备删除!");
    				if (!FileUtils.delFile(descFileName)) {
    					logger.debug("删除目标文件 " + descFileName + " 失败!");
    					return false;
    				}
    			} else {
    				logger.debug("复制文件失败,目标文件 " + descFileName + " 已存在!");
    				return false;
    			}
    		} else {
    			if (!descFile.getParentFile().exists()) {
    				// 如果目标文件所在的目录不存在,则创建目录
    				logger.debug("目标文件所在的目录不存在,创建目录!");
    				// 创建目标文件所在的目录
    				if (!descFile.getParentFile().mkdirs()) {
    					logger.debug("创建目标文件所在的目录失败!");
    					return false;
    				}
    			}
    		}
    
    		// 准备复制文件
    		// 读取的位数
    		int readByte = 0;
    		InputStream ins = null;
    		OutputStream outs = null;
    		try {
    			// 打开源文件
    			ins = new FileInputStream(srcFile);
    			// 打开目标文件的输出流
    			outs = new FileOutputStream(descFile);
    			byte[] buf = new byte[1024];
    			// 一次读取1024个字节,当readByte为-1时表示文件已经读取完毕
    			while ((readByte = ins.read(buf)) != -1) {
    				// 将读取的字节流写入到输出流
    				outs.write(buf, 0, readByte);
    			}
    			logger.debug("复制单个文件 " + srcFileName + " 到" + descFileName
    					+ "成功!");
    			return true;
    		} catch (Exception e) {
    			logger.debug("复制文件失败:" + e.getMessage());
    			return false;
    		} finally {
    			// 关闭输入输出流,首先关闭输出流,然后再关闭输入流
    			if (outs != null) {
    				try {
    					outs.close();
    				} catch (IOException oute) {
    					oute.printStackTrace();
    				}
    			}
    			if (ins != null) {
    				try {
    					ins.close();
    				} catch (IOException ine) {
    					ine.printStackTrace();
    				}
    			}
    		}
    	}
    
    	/**
    	 * 复制整个目录的内容,如果目标目录存在,则不覆盖
    	 * @param srcDirName 源目录名
    	 * @param descDirName 目标目录名
    	 * @return 如果复制成功返回true,否则返回false
    	 */
    	public static boolean copyDirectory(String srcDirName, String descDirName) {
    		return FileUtils.copyDirectoryCover(srcDirName, descDirName,
    				false);
    	}
    
    	/**
    	 * 复制整个目录的内容 
    	 * @param srcDirName 源目录名
    	 * @param descDirName 目标目录名
    	 * @param coverlay 如果目标目录存在,是否覆盖
    	 * @return 如果复制成功返回true,否则返回false
    	 */
    	public static boolean copyDirectoryCover(String srcDirName,
    			String descDirName, boolean coverlay) {
    		File srcDir = new File(srcDirName);
    		// 判断源目录是否存在
    		if (!srcDir.exists()) {
    			logger.debug("复制目录失败,源目录 " + srcDirName + " 不存在!");
    			return false;
    		}
    		// 判断源目录是否是目录
    		else if (!srcDir.isDirectory()) {
    			logger.debug("复制目录失败," + srcDirName + " 不是一个目录!");
    			return false;
    		}
    		// 如果目标文件夹名不以文件分隔符结尾,自动添加文件分隔符
    		String descDirNames = descDirName;
    		if (!descDirNames.endsWith(File.separator)) {
    			descDirNames = descDirNames + File.separator;
    		}
    		File descDir = new File(descDirNames);
    		// 如果目标文件夹存在
    		if (descDir.exists()) {
    			if (coverlay) {
    				// 允许覆盖目标目录
    				logger.debug("目标目录已存在,准备删除!");
    				if (!FileUtils.delFile(descDirNames)) {
    					logger.debug("删除目录 " + descDirNames + " 失败!");
    					return false;
    				}
    			} else {
    				logger.debug("目标目录复制失败,目标目录 " + descDirNames + " 已存在!");
    				return false;
    			}
    		} else {
    			// 创建目标目录
    			logger.debug("目标目录不存在,准备创建!");
    			if (!descDir.mkdirs()) {
    				logger.debug("创建目标目录失败!");
    				return false;
    			}
    
    		}
    
    		boolean flag = true;
    		// 列出源目录下的所有文件名和子目录名
    		File[] files = srcDir.listFiles();
    		for (int i = 0; i < files.length; i++) {
    			// 如果是一个单个文件,则直接复制
    			if (files[i].isFile()) {
    				flag = FileUtils.copyFile(files[i].getAbsolutePath(),
    						descDirName + files[i].getName());
    				// 如果拷贝文件失败,则退出循环
    				if (!flag) {
    					break;
    				}
    			}
    			// 如果是子目录,则继续复制目录
    			if (files[i].isDirectory()) {
    				flag = FileUtils.copyDirectory(files[i]
    						.getAbsolutePath(), descDirName + files[i].getName());
    				// 如果拷贝目录失败,则退出循环
    				if (!flag) {
    					break;
    				}
    			}
    		}
    
    		if (!flag) {
    			logger.debug("复制目录 " + srcDirName + " 到 " + descDirName + " 失败!");
    			return false;
    		}
    		logger.debug("复制目录 " + srcDirName + " 到 " + descDirName + " 成功!");
    		return true;
    
    	}
    
    	/**
    	 * 
    	 * 删除文件,可以删除单个文件或文件夹
    	 * 
    	 * @param fileName 被删除的文件名
    	 * @return 如果删除成功,则返回true,否是返回false
    	 */
    	public static boolean delFile(String fileName) {
     		File file = new File(fileName);
    		if (!file.exists()) {
    			logger.debug(fileName + " 文件不存在!");
    			return true;
    		} else {
    			if (file.isFile()) {
    				return FileUtils.deleteFile(fileName);
    			} else {
    				return FileUtils.deleteDirectory(fileName);
    			}
    		}
    	}
    
    	/**
    	 * 
    	 * 删除单个文件
    	 * 
    	 * @param fileName 被删除的文件名
    	 * @return 如果删除成功,则返回true,否则返回false
    	 */
    	public static boolean deleteFile(String fileName) {
    		File file = new File(fileName);
    		if (file.exists() && file.isFile()) {
    			if (file.delete()) {
    				logger.debug("删除文件 " + fileName + " 成功!");
    				return true;
    			} else {
    				logger.debug("删除文件 " + fileName + " 失败!");
    				return false;
    			}
    		} else {
    			logger.debug(fileName + " 文件不存在!");
    			return true;
    		}
    	}
    
    	/**
    	 * 
    	 * 删除目录及目录下的文件
    	 * 
    	 * @param dirName 被删除的目录所在的文件路径
    	 * @return 如果目录删除成功,则返回true,否则返回false
    	 */
    	public static boolean deleteDirectory(String dirName) {
    		String dirNames = dirName;
    		if (!dirNames.endsWith(File.separator)) {
    			dirNames = dirNames + File.separator;
    		}
    		File dirFile = new File(dirNames);
    		if (!dirFile.exists() || !dirFile.isDirectory()) {
    			logger.debug(dirNames + " 目录不存在!");
    			return true;
    		}
    		boolean flag = true;
    		// 列出全部文件及子目录
    		File[] files = dirFile.listFiles();
    		for (int i = 0; i < files.length; i++) {
    			// 删除子文件
    			if (files[i].isFile()) {
    				flag = FileUtils.deleteFile(files[i].getAbsolutePath());
    				// 如果删除文件失败,则退出循环
    				if (!flag) {
    					break;
    				}
    			}
    			// 删除子目录
    			else if (files[i].isDirectory()) {
    				flag = FileUtils.deleteDirectory(files[i]
    						.getAbsolutePath());
    				// 如果删除子目录失败,则退出循环
    				if (!flag) {
    					break;
    				}
    			}
    		}
    
    		if (!flag) {
    			logger.debug("删除目录失败!");
    			return false;
    		}
    		// 删除当前目录
    		if (dirFile.delete()) {
    			logger.debug("删除目录 " + dirName + " 成功!");
    			return true;
    		} else {
    			logger.debug("删除目录 " + dirName + " 失败!");
    			return false;
    		}
    
    	}
    
    	/**
    	 * 创建单个文件
    	 * @param descFileName 文件名,包含路径
    	 * @return 如果创建成功,则返回true,否则返回false
    	 */
    	public static boolean createFile(String descFileName) {
    		File file = new File(descFileName);
    		if (file.exists()) {
    			logger.debug("文件 " + descFileName + " 已存在!");
    			return false;
    		}
    		if (descFileName.endsWith(File.separator)) {
    			logger.debug(descFileName + " 为目录,不能创建目录!");
    			return false;
    		}
    		if (!file.getParentFile().exists()) {
    			// 如果文件所在的目录不存在,则创建目录
    			if (!file.getParentFile().mkdirs()) {
    				logger.debug("创建文件所在的目录失败!");
    				return false;
    			}
    		}
    
    		// 创建文件
    		try {
    			if (file.createNewFile()) {
    				logger.debug(descFileName + " 文件创建成功!");
    				return true;
    			} else {
    				logger.debug(descFileName + " 文件创建失败!");
    				return false;
    			}
    		} catch (Exception e) {
    			e.printStackTrace();
    			logger.debug(descFileName + " 文件创建失败!");
    			return false;
    		}
    
    	}
    
    	/**
    	 * 创建目录
    	 * @param descDirName 目录名,包含路径
    	 * @return 如果创建成功,则返回true,否则返回false
    	 */
    	public static boolean createDirectory(String descDirName) {
    		String descDirNames = descDirName;
    		if (!descDirNames.endsWith(File.separator)) {
    			descDirNames = descDirNames + File.separator;
    		}
    		File descDir = new File(descDirNames);
    		if (descDir.exists()) {
    			logger.debug("目录 " + descDirNames + " 已存在!");
    			return false;
    		}
    		// 创建目录
    		if (descDir.mkdirs()) {
    			logger.debug("目录 " + descDirNames + " 创建成功!");
    			return true;
    		} else {
    			logger.debug("目录 " + descDirNames + " 创建失败!");
    			return false;
    		}
    
    	}
    
    	/**
    	 * 写入文件
    	 * @param file 要写入的文件
    	 */
    	public static void writeToFile(String fileName, String content, boolean append) {
    		try {
    			FileUtils.write(new File(fileName), content, "utf-8", append);
    			logger.debug("文件 " + fileName + " 写入成功!");
    		} catch (IOException e) {
    			logger.debug("文件 " + fileName + " 写入失败! " + e.getMessage());
    		}
    	}
    
    	/**
    	 * 写入文件
    	 * @param file 要写入的文件
    	 */
    	public static void writeToFile(String fileName, String content, String encoding, boolean append) {
    		try {
    			FileUtils.write(new File(fileName), content, encoding, append);
    			logger.debug("文件 " + fileName + " 写入成功!");
    		} catch (IOException e) {
    			logger.debug("文件 " + fileName + " 写入失败! " + e.getMessage());
    		}
    	}
    	
    	/**
    	 * 压缩文件或目录
    	 * @param srcDirName 压缩的根目录
    	 * @param fileName 根目录下的待压缩的文件名或文件夹名,其中*或""表示跟目录下的全部文件
    	 * @param descFileName 目标zip文件
    	 */
    	public static void zipFiles(String srcDirName, String fileName,
    			String descFileName) {
    		// 判断目录是否存在
    		if (srcDirName == null) {
    			logger.debug("文件压缩失败,目录 " + srcDirName + " 不存在!");
    			return;
    		}
    		File fileDir = new File(srcDirName);
    		if (!fileDir.exists() || !fileDir.isDirectory()) {
    			logger.debug("文件压缩失败,目录 " + srcDirName + " 不存在!");
    			return;
    		}
    		String dirPath = fileDir.getAbsolutePath();
    		File descFile = new File(descFileName);
    		try {
    			ZipOutputStream zouts = new ZipOutputStream(new FileOutputStream(
    					descFile));
    			if ("*".equals(fileName) || "".equals(fileName)) {
    				FileUtils.zipDirectoryToZipFile(dirPath, fileDir, zouts);
    			} else {
    				File file = new File(fileDir, fileName);
    				if (file.isFile()) {
    					FileUtils.zipFilesToZipFile(dirPath, file, zouts);
    				} else {
    					FileUtils
    							.zipDirectoryToZipFile(dirPath, file, zouts);
    				}
    			}
    			zouts.close();
    			logger.debug(descFileName + " 文件压缩成功!");
    		} catch (Exception e) {
    			logger.debug("文件压缩失败:" + e.getMessage());
    			e.printStackTrace();
    		}
    
    	}
    
    	/**
    	 * 解压缩ZIP文件,将ZIP文件里的内容解压到descFileName目录下
    	 * @param zipFileName 需要解压的ZIP文件
    	 * @param descFileName 目标文件
    	 */
    	public static boolean unZipFiles(String zipFileName, String descFileName) {
    		String descFileNames = descFileName;
    		if (!descFileNames.endsWith(File.separator)) {
    			descFileNames = descFileNames + File.separator;
    		}		
            try {
    			// 根据ZIP文件创建ZipFile对象
    			ZipFile zipFile = new ZipFile(zipFileName);
    			ZipEntry entry = null;
    			String entryName = null;
    			String descFileDir = null;
    			byte[] buf = new byte[4096];
    			int readByte = 0;
    			// 获取ZIP文件里所有的entry
    			@SuppressWarnings("rawtypes")
    			Enumeration enums = zipFile.getEntries();
    			// 遍历所有entry
    			while (enums.hasMoreElements()) {
    				entry = (ZipEntry) enums.nextElement();
    				// 获得entry的名字
    				entryName = entry.getName();
    				descFileDir = descFileNames + entryName;
    				if (entry.isDirectory()) {
    					// 如果entry是一个目录,则创建目录
    					new File(descFileDir).mkdirs();
    					continue;
    				} else {
    					// 如果entry是一个文件,则创建父目录
    					new File(descFileDir).getParentFile().mkdirs();
    				}
    				File file = new File(descFileDir);
    				// 打开文件输出流
    				OutputStream os = new FileOutputStream(file);
    				// 从ZipFile对象中打开entry的输入流
    		        InputStream is = zipFile.getInputStream(entry);
    				while ((readByte = is.read(buf)) != -1) {
    					os.write(buf, 0, readByte);
    				}
    				os.close();
    				is.close();
    			}
    			zipFile.close();
    			logger.debug("文件解压成功!");
    			return true;
    		} catch (Exception e) {
    			logger.debug("文件解压失败:" + e.getMessage());
    			return false;
    		}
    	}
    
    	/**
    	 * 将目录压缩到ZIP输出流
    	 * @param dirPath 目录路径
    	 * @param fileDir 文件信息
    	 * @param zouts 输出流
    	 */
    	public static void zipDirectoryToZipFile(String dirPath, File fileDir, ZipOutputStream zouts) {
    		if (fileDir.isDirectory()) {
    			File[] files = fileDir.listFiles();
    			// 空的文件夹
    			if (files.length == 0) {
    				// 目录信息
    				ZipEntry entry = new ZipEntry(getEntryName(dirPath, fileDir));
    				try {
    					zouts.putNextEntry(entry);
    					zouts.closeEntry();
    				} catch (Exception e) {
    					e.printStackTrace();
    				}
    				return;
    			}
    
    			for (int i = 0; i < files.length; i++) {
    				if (files[i].isFile()) {
    					// 如果是文件,则调用文件压缩方法
    					FileUtils
    							.zipFilesToZipFile(dirPath, files[i], zouts);
    				} else {
    					// 如果是目录,则递归调用
    					FileUtils.zipDirectoryToZipFile(dirPath, files[i],
    							zouts);
    				}
    			}
    		}
    	}
    
    	/**
    	 * 将文件压缩到ZIP输出流
    	 * @param dirPath 目录路径
    	 * @param file 文件
    	 * @param zouts 输出流
    	 */
    	public static void zipFilesToZipFile(String dirPath, File file, ZipOutputStream zouts) {
    		FileInputStream fin = null;
    		ZipEntry entry = null;
    		// 创建复制缓冲区
    		byte[] buf = new byte[4096];
    		int readByte = 0;
    		if (file.isFile()) {
    			try {
    				// 创建一个文件输入流
    				fin = new FileInputStream(file);
    				// 创建一个ZipEntry
    				entry = new ZipEntry(getEntryName(dirPath, file));
    				// 存储信息到压缩文件
    				zouts.putNextEntry(entry);
    				// 复制字节到压缩文件
    				while ((readByte = fin.read(buf)) != -1) {
    					zouts.write(buf, 0, readByte);
    				}
    				zouts.closeEntry();
    				fin.close();
    				System.out
    						.println("添加文件 " + file.getAbsolutePath() + " 到zip文件中!");
    			} catch (Exception e) {
    				e.printStackTrace();
    			}
    		}
    	}
    
    	/**
    	 * 获取待压缩文件在ZIP文件中entry的名字,即相对于跟目录的相对路径名
    	 * @param dirPat 目录名
    	 * @param file entry文件名
    	 * @return
    	 */
    	private static String getEntryName(String dirPath, File file) {
    		String dirPaths = dirPath;
    		if (!dirPaths.endsWith(File.separator)) {
    			dirPaths = dirPaths + File.separator;
    		}
    		String filePath = file.getAbsolutePath();
    		// 对于目录,必须在entry名字后面加上"/",表示它将以目录项存储
    		if (file.isDirectory()) {
    			filePath += "/";
    		}
    		int index = filePath.indexOf(dirPaths);
    
    		return filePath.substring(index + dirPaths.length());
    	}
    
    	/**
    	 * 根据“文件名的后缀”获取文件内容类型(而非根据File.getContentType()读取的文件类型)
    	 * @param returnFileName 带验证的文件名
    	 * @return 返回文件类型
    	 */
    	public static String getContentType(String returnFileName) {
    		String contentType = "application/octet-stream";
    		if (returnFileName.lastIndexOf(".") < 0)
    			return contentType;
    		returnFileName = returnFileName.toLowerCase();
    		returnFileName = returnFileName.substring(returnFileName.lastIndexOf(".") + 1);
    		if (returnFileName.equals("html") || returnFileName.equals("htm") || returnFileName.equals("shtml")) {
    			contentType = "text/html";
    		} else if (returnFileName.equals("apk")) {
    			contentType = "application/vnd.android.package-archive";
    		} else if (returnFileName.equals("sis")) {
    			contentType = "application/vnd.symbian.install";
    		} else if (returnFileName.equals("sisx")) {
    			contentType = "application/vnd.symbian.install";
    		} else if (returnFileName.equals("exe")) {
    			contentType = "application/x-msdownload";
    		} else if (returnFileName.equals("msi")) {
    			contentType = "application/x-msdownload";
    		} else if (returnFileName.equals("css")) {
    			contentType = "text/css";
    		} else if (returnFileName.equals("xml")) {
    			contentType = "text/xml";
    		} else if (returnFileName.equals("gif")) {
    			contentType = "image/gif";
    		} else if (returnFileName.equals("jpeg") || returnFileName.equals("jpg")) {
    			contentType = "image/jpeg";
    		} else if (returnFileName.equals("js")) {
    			contentType = "application/x-javascript";
    		} else if (returnFileName.equals("atom")) {
    			contentType = "application/atom+xml";
    		} else if (returnFileName.equals("rss")) {
    			contentType = "application/rss+xml";
    		} else if (returnFileName.equals("mml")) {
    			contentType = "text/mathml";
    		} else if (returnFileName.equals("txt")) {
    			contentType = "text/plain";
    		} else if (returnFileName.equals("jad")) {
    			contentType = "text/vnd.sun.j2me.app-descriptor";
    		} else if (returnFileName.equals("wml")) {
    			contentType = "text/vnd.wap.wml";
    		} else if (returnFileName.equals("htc")) {
    			contentType = "text/x-component";
    		} else if (returnFileName.equals("png")) {
    			contentType = "image/png";
    		} else if (returnFileName.equals("tif") || returnFileName.equals("tiff")) {
    			contentType = "image/tiff";
    		} else if (returnFileName.equals("wbmp")) {
    			contentType = "image/vnd.wap.wbmp";
    		} else if (returnFileName.equals("ico")) {
    			contentType = "image/x-icon";
    		} else if (returnFileName.equals("jng")) {
    			contentType = "image/x-jng";
    		} else if (returnFileName.equals("bmp")) {
    			contentType = "image/x-ms-bmp";
    		} else if (returnFileName.equals("svg")) {
    			contentType = "image/svg+xml";
    		} else if (returnFileName.equals("jar") || returnFileName.equals("var") 
    				|| returnFileName.equals("ear")) {
    			contentType = "application/java-archive";
    		} else if (returnFileName.equals("doc")) {
    			contentType = "application/msword";
    		} else if (returnFileName.equals("pdf")) {
    			contentType = "application/pdf";
    		} else if (returnFileName.equals("rtf")) {
    			contentType = "application/rtf";
    		} else if (returnFileName.equals("xls")) {
    			contentType = "application/vnd.ms-excel";
    		} else if (returnFileName.equals("ppt")) {
    			contentType = "application/vnd.ms-powerpoint";
    		} else if (returnFileName.equals("7z")) {
    			contentType = "application/x-7z-compressed";
    		} else if (returnFileName.equals("rar")) {
    			contentType = "application/x-rar-compressed";
    		} else if (returnFileName.equals("swf")) {
    			contentType = "application/x-shockwave-flash";
    		} else if (returnFileName.equals("rpm")) {
    			contentType = "application/x-redhat-package-manager";
    		} else if (returnFileName.equals("der") || returnFileName.equals("pem")
    				|| returnFileName.equals("crt")) {
    			contentType = "application/x-x509-ca-cert";
    		} else if (returnFileName.equals("xhtml")) {
    			contentType = "application/xhtml+xml";
    		} else if (returnFileName.equals("zip")) {
    			contentType = "application/zip";
    		} else if (returnFileName.equals("mid") || returnFileName.equals("midi") 
    				|| returnFileName.equals("kar")) {
    			contentType = "audio/midi";
    		} else if (returnFileName.equals("mp3")) {
    			contentType = "audio/mpeg";
    		} else if (returnFileName.equals("ogg")) {
    			contentType = "audio/ogg";
    		} else if (returnFileName.equals("m4a")) {
    			contentType = "audio/x-m4a";
    		} else if (returnFileName.equals("ra")) {
    			contentType = "audio/x-realaudio";
    		} else if (returnFileName.equals("3gpp")
    				|| returnFileName.equals("3gp")) {
    			contentType = "video/3gpp";
    		} else if (returnFileName.equals("mp4")) {
    			contentType = "video/mp4";
    		} else if (returnFileName.equals("mpeg")
    				|| returnFileName.equals("mpg")) {
    			contentType = "video/mpeg";
    		} else if (returnFileName.equals("mov")) {
    			contentType = "video/quicktime";
    		} else if (returnFileName.equals("flv")) {
    			contentType = "video/x-flv";
    		} else if (returnFileName.equals("m4v")) {
    			contentType = "video/x-m4v";
    		} else if (returnFileName.equals("mng")) {
    			contentType = "video/x-mng";
    		} else if (returnFileName.equals("asx") || returnFileName.equals("asf")) {
    			contentType = "video/x-ms-asf";
    		} else if (returnFileName.equals("wmv")) {
    			contentType = "video/x-ms-wmv";
    		} else if (returnFileName.equals("avi")) {
    			contentType = "video/x-msvideo";
    		}
    		return contentType;
    	}
    	
    	/**
    	 * 向浏览器发送文件下载,支持断点续传
    	 * @param file 要下载的文件
    	 * @param request 请求对象
    	 * @param response 响应对象
    	 * @return 返回错误信息,无错误信息返回null
    	 */
    	public static String downFile(File file, HttpServletRequest request, HttpServletResponse response){
    		 return downFile(file, request, response, null);
    	}
    	
    	/**
    	 * 向浏览器发送文件下载,支持断点续传
    	 * @param file 要下载的文件
    	 * @param request 请求对象
    	 * @param response 响应对象
    	 * @param fileName 指定下载的文件名
    	 * @return 返回错误信息,无错误信息返回null
    	 */
    	public static String downFile(File file, HttpServletRequest request, HttpServletResponse response, String fileName){
    		String error  = null;
    		if (file != null && file.exists()) {
    			if (file.isFile()) {
    				if (file.length() <= 0) {
    					error = "该文件是一个空文件。";
    				}
    				if (!file.canRead()) {
    					error = "该文件没有读取权限。";
    				}
    			} else {
    				error = "该文件是一个文件夹。";
    			}
    		} else {
    			error = "文件已丢失或不存在!";
    		}
    		if (error != null){
    			logger.debug("---------------" + file + " " + error);
    			return error;
    		}
    
    		long fileLength = file.length(); // 记录文件大小
    		long pastLength = 0; 	// 记录已下载文件大小
    		int rangeSwitch = 0; 	// 0:从头开始的全文下载;1:从某字节开始的下载(bytes=27000-);2:从某字节开始到某字节结束的下载(bytes=27000-39000)
    		long toLength = 0; 		// 记录客户端需要下载的字节段的最后一个字节偏移量(比如bytes=27000-39000,则这个值是为39000)
    		long contentLength = 0; // 客户端请求的字节总量
    		String rangeBytes = ""; // 记录客户端传来的形如“bytes=27000-”或者“bytes=27000-39000”的内容
    		RandomAccessFile raf = null; // 负责读取数据
    		OutputStream os = null; 	// 写出数据
    		OutputStream out = null; 	// 缓冲
    		byte b[] = new byte[1024]; 	// 暂存容器
    
    		if (request.getHeader("Range") != null) { // 客户端请求的下载的文件块的开始字节
    			response.setStatus(javax.servlet.http.HttpServletResponse.SC_PARTIAL_CONTENT);
    			logger.debug("request.getHeader(\"Range\") = " + request.getHeader("Range"));
    			rangeBytes = request.getHeader("Range").replaceAll("bytes=", "");
    			if (rangeBytes.indexOf('-') == rangeBytes.length() - 1) {// bytes=969998336-
    				rangeSwitch = 1;
    				rangeBytes = rangeBytes.substring(0, rangeBytes.indexOf('-'));
    				pastLength = Long.parseLong(rangeBytes.trim());
    				contentLength = fileLength - pastLength; // 客户端请求的是 969998336  之后的字节
    			} else { // bytes=1275856879-1275877358
    				rangeSwitch = 2;
    				String temp0 = rangeBytes.substring(0, rangeBytes.indexOf('-'));
    				String temp2 = rangeBytes.substring(rangeBytes.indexOf('-') + 1, rangeBytes.length());
    				pastLength = Long.parseLong(temp0.trim()); // bytes=1275856879-1275877358,从第 1275856879 个字节开始下载
    				toLength = Long.parseLong(temp2); // bytes=1275856879-1275877358,到第 1275877358 个字节结束
    				contentLength = toLength - pastLength; // 客户端请求的是 1275856879-1275877358 之间的字节
    			}
    		} else { // 从开始进行下载
    			contentLength = fileLength; // 客户端要求全文下载
    		}
    
    		// 如果设设置了Content-Length,则客户端会自动进行多线程下载。如果不希望支持多线程,则不要设置这个参数。 响应的格式是:
    		// Content-Length: [文件的总大小] - [客户端请求的下载的文件块的开始字节]
    		// ServletActionContext.getResponse().setHeader("Content- Length", new Long(file.length() - p).toString());
    		response.reset(); // 告诉客户端允许断点续传多线程连接下载,响应的格式是:Accept-Ranges: bytes
    		if (pastLength != 0) {
    			response.setHeader("Accept-Ranges", "bytes");// 如果是第一次下,还没有断点续传,状态是默认的 200,无需显式设置;响应的格式是:HTTP/1.1 200 OK
    			// 不是从最开始下载, 响应的格式是: Content-Range: bytes [文件块的开始字节]-[文件的总大小 - 1]/[文件的总大小]
    			logger.debug("---------------不是从开始进行下载!服务器即将开始断点续传...");
    			switch (rangeSwitch) {
    				case 1: { // 针对 bytes=27000- 的请求
    					String contentRange = new StringBuffer("bytes ").append(new Long(pastLength).toString()).append("-")
    							.append(new Long(fileLength - 1).toString()).append("/").append(new Long(fileLength).toString()).toString();
    					response.setHeader("Content-Range", contentRange);
    					break;
    				}
    				case 2: { // 针对 bytes=27000-39000 的请求
    					String contentRange = rangeBytes + "/" + new Long(fileLength).toString();
    					response.setHeader("Content-Range", contentRange);
    					break;
    				}
    				default: {
    					break;
    				}
    			}
    		} else {
    			// 是从开始下载
    			logger.debug("---------------是从开始进行下载!");
    		}
    
    		try {
    			response.addHeader("Content-Disposition", "attachment; filename=\"" + 
    					Encodes.urlEncode(StringUtils.isBlank(fileName) ? file.getName() : fileName) + "\"");
    			response.setContentType(getContentType(file.getName())); // set the MIME type.
    			response.addHeader("Content-Length", String.valueOf(contentLength));
    			os = response.getOutputStream();
    			out = new BufferedOutputStream(os);
    			raf = new RandomAccessFile(file, "r");
    			try {
    				switch (rangeSwitch) {
    					case 0: { // 普通下载,或者从头开始的下载 同1
    					}
    					case 1: { // 针对 bytes=27000- 的请求
    						raf.seek(pastLength); // 形如 bytes=969998336- 的客户端请求,跳过 969998336 个字节
    						int n = 0;
    						while ((n = raf.read(b, 0, 1024)) != -1) {
    							out.write(b, 0, n);
    						}
    						break;
    					}
    					case 2: { // 针对 bytes=27000-39000 的请求
    						raf.seek(pastLength); // 形如 bytes=1275856879-1275877358 的客户端请求,找到第 1275856879 个字节
    						int n = 0;
    						long readLength = 0; // 记录已读字节数
    						while (readLength <= contentLength - 1024) {// 大部分字节在这里读取
    							n = raf.read(b, 0, 1024);
    							readLength += 1024;
    							out.write(b, 0, n);
    						}
    						if (readLength <= contentLength) { // 余下的不足 1024 个字节在这里读取
    							n = raf.read(b, 0, (int) (contentLength - readLength));
    							out.write(b, 0, n);
    						}
    						break;
    					}
    					default: {
    						break;
    					}
    				}
    				out.flush();
    				logger.debug("---------------下载完成!");
    			} catch (IOException ie) {
    				/**
    				 * 在写数据的时候, 对于 ClientAbortException 之类的异常,
    				 * 是因为客户端取消了下载,而服务器端继续向浏览器写入数据时, 抛出这个异常,这个是正常的。
    				 * 尤其是对于迅雷这种吸血的客户端软件, 明明已经有一个线程在读取 bytes=1275856879-1275877358,
    				 * 如果短时间内没有读取完毕,迅雷会再启第二个、第三个。。。线程来读取相同的字节段, 直到有一个线程读取完毕,迅雷会 KILL
    				 * 掉其他正在下载同一字节段的线程, 强行中止字节读出,造成服务器抛 ClientAbortException。
    				 * 所以,我们忽略这种异常
    				 */
    				logger.debug("提醒:向客户端传输时出现IO异常,但此异常是允许的,有可能客户端取消了下载,导致此异常,不用关心!");
    			}
    		} catch (Exception e) {
    			logger.error(e.getMessage(), e);
    		} finally {
    			if (out != null) {
    				try {
    					out.close();
    				} catch (IOException e) {
    					logger.error(e.getMessage(), e);
    				}
    			}
    			if (raf != null) {
    				try {
    					raf.close();
    				} catch (IOException e) {
    					logger.error(e.getMessage(), e);
    				}
    			}
    		}
    		return null;
    	}
    
    	/**
    	 * 修正路径,将 \\ 或 / 等替换为 File.separator
    	 * @param path 待修正的路径
    	 * @return 修正后的路径
    	 */
    	public static String path(String path){
    		String p = StringUtils.replace(path, "\\", "/");
    		p = StringUtils.join(StringUtils.split(p, "/"), "/");
    		if (!StringUtils.startsWithAny(p, "/") && StringUtils.startsWithAny(path, "\\", "/")){
    			p += "/";
    		}
    		if (!StringUtils.endsWithAny(p, "/") && StringUtils.endsWithAny(path, "\\", "/")){
    			p = p + "/";
    		}
    		if (path != null && path.startsWith("/")){
    			p = "/" + p; // linux下路径
    		}
    		return p;
    	}
    	
    	/**
    	 * 获目录下的文件列表
    	 * @param dir 搜索目录
    	 * @param searchDirs 是否是搜索目录
    	 * @return 文件列表
    	 */
    	public static List<String> findChildrenList(File dir, boolean searchDirs) {
    		List<String> files = Lists.newArrayList();
    		for (String subFiles : dir.list()) {
    			File file = new File(dir + "/" + subFiles);
    			if (((searchDirs) && (file.isDirectory())) || ((!searchDirs) && (!file.isDirectory()))) {
    				files.add(file.getName());
    			}
    		}
    		return files;
    	}
    
    	/**
    	 * 获取文件扩展名(返回小写)
    	 * @param fileName 文件名
    	 * @return 例如:test.jpg  返回:  jpg
    	 */
    	public static String getFileExtension(String fileName) {
    		if ((fileName == null) || (fileName.lastIndexOf(".") == -1) || (fileName.lastIndexOf(".") == fileName.length() - 1)) {
    			return null;
    		}
    		return StringUtils.lowerCase(fileName.substring(fileName.lastIndexOf(".") + 1));
    	}
    
    	/**
    	 * 获取文件名,不包含扩展名
    	 * @param fileName 文件名
    	 * @return 例如:d:\files\test.jpg  返回:d:\files\test
    	 */
    	public static String getFileNameWithoutExtension(String fileName) {
    		if ((fileName == null) || (fileName.lastIndexOf(".") == -1)) {
    			return null;
    		}
    		return fileName.substring(0, fileName.lastIndexOf("."));
    	}
    }
    
    

    Excel标题相关配置

        Excel表头相关配置,在Student实体类中,增加注解
        
        @ExcelField(title="学生姓名", align=1, sort=90)
        align:对齐方式
        sort:顺序
    

    应用的框架是jeesite

      好啦,到这就结束啦,下次再见
    
    展开全文
  • 这段时间正好做了个在ssh框架下将数据生成Excel文件导出的功能,趁着还记得,赶快把它贴出来pom.xml配置(Excel需要导的jar包)excel.poipoi-commons-jexl2.1.1excel.poipoi-core3.10excel.poipoi-jxls-core1.0.5excel...

    这段时间正好做了个在ssh框架下将数据生成Excel文件导出的功能,趁着还记得,赶快把它贴出来

    pom.xml配置(Excel需要导的jar包)

    excel.poi

    poi-commons-jexl

    2.1.1

    excel.poi

    poi-core

    3.10

    excel.poi

    poi-jxls-core

    1.0.5

    excel.poi

    poi-ooxml

    3.10

    Struts.xml配置

    application/vnd.ms-excel

    attachment;filename="CurriExcel.xls"

    excelFile

    表格实现代码

    HSSFWorkbook workbook = new HSSFWorkbook(); // 创建一个excel

    for (int j = 0; j < classList.size(); j++) {// 循环数据

    ExamineeClass eClass = (ExamineeClass) classList.get(j);

    HSSFCellStyle style = workbook.createCellStyle(); // 设置表头的类型

    style.setAlignment(HSSFCellStyle.ALIGN_CENTER);//内容左右居中

    HSSFCellStyle style1 = workbook.createCellStyle(); // 设置数据类型

    style1.setAlignment(HSSFCellStyle.ALIGN_CENTER);//内容左右居中

    HSSFFont font = workbook.createFont(); // 设置字体

    HSSFSheet sheet = workbook.createSheet(eClass.getClassName()); // 创建一个sheet

    HSSFHeader header = sheet.getHeader();// 设置sheet的头

    HSSFCell cell = null; // Excel的列

    HSSFRow row = null; // Excel的行

    /*

    * 设置表头:对Excel每列取名 (必须根据你取的数据编写)

    */

    String[] tableHeader = new String[8];

    tableHeader[0] = eClass.getClassName();//列的第一行命名

    String a[] = startDate.split("-");//把日期年月日分开

    int year = Integer.parseInt(a[0]);

    int month = Integer.parseInt(a[1]);

    int day = Integer.parseInt(a[2]);

    tableHeader[1] = getDate(year, month - 1, day);

    for (int k = 1; k < 7; k++) {//把各个日期命名为列名

    day += 1;

    tableHeader[k + 1] = getDate(year, month - 1, day);

    }

    /*

    * 下面的都可以拷贝不用编写

    */

    short cellNumber = (short) tableHeader.length;// 表的列数

    /**

    * 根据是否取出数据,设置header信息

    *

    */

    if (SignList.size() < 1) {

    header.setCenter("查无资料");

    } else {

    header.setCenter("学生课表");

    row = sheet.createRow(0);// 第0行

    row.setHeight((short) 400);//设置行高

    for (int k = 0; k < cellNumber; k++) {

    cell = row.createCell(k);// 创建第0行第k列

    cell.setCellValue(tableHeader[k]);// 设置第0行第k列的值

    sheet.setColumnWidth(k, 6000);// 设置列的宽度

    font.setColor(HSSFFont.COLOR_NORMAL); // 设置单元格字体的颜色.

    font.setFontHeight((short) 350); // 设置单元字体高度

    style1.setFont(font);// 设置字体风格

    cell.setCellStyle(style1);//设置样式

    style.setFillForegroundColor(HSSFColor.ROSE.index); // 前景色的设定

    style.setFillPattern(CellStyle.SOLID_FOREGROUND);// 填充模式

    cell.setCellStyle(style);

    }

    String times[] = { "8:30-10:30", "10:30-12:00", "14:00-15:30", "15:30-17:30", "19:00-20:30",

    "20:30-22:00" };

    for (int h = 0; h < 6; h++) {// 设置第一列

    row = sheet.createRow(h + 1);

    row.setHeight((short) 400);

    cell = row.createCell(0);

    cell.setCellValue(times[h]);// 设置第1列0行

    sheet.setColumnWidth(0, 6000);// 设置列的宽度

    font.setColor(HSSFFont.COLOR_NORMAL); // 设置单元格字体的颜色.

    font.setFontHeight((short) 350); // 设置单元字体高度

    style1.setFont(font);// 设置字体风格

    cell.setCellStyle(style1);

    style.setFillForegroundColor(HSSFColor.ROSE.index);

    style.setFillPattern(CellStyle.SOLID_FOREGROUND);

    cell.setCellStyle(style);

    }

    /*

    * // 给excel填充数据这里需要编写

    *

    */

    for (int i = 0; i < SignList.size(); i++) {// 循环所有的数据

    TeacherCurriModel sign = (TeacherCurriModel) SignList.get(i);// 获取sign对象

    row = sheet.getRow(0);// 0行

    if (sign.getClassname().equals(row.getCell(0).getStringCellValue())) {

    String date = sign.getDate();

    String tString = sign.getTimeperiods();

    int rownum = 0;

    int cellnum = 0;

    for (int k = 1; k < cellNumber; k++) {// 列

    row = sheet.getRow(0);// 行

    String date1 = row.getCell(k).getStringCellValue();

    if (date1.equals(date)) {

    cellnum = k;// 找到列id

    break;

    }

    }

    for (int c = 1; c < 7; c++) {

    row = sheet.getRow(c);

    String time = row.getCell(0).getStringCellValue();

    if (time.equals(tString)) {

    rownum = c;// 找到行id

    break;

    }

    }

    row = sheet.getRow((short) rownum);

    row.setHeight((short) 400);

    cell = row.createCell(cellnum);

    HSSFCellStyle style2 = workbook.createCellStyle();

    style2.setAlignment(HSSFCellStyle.ALIGN_CENTER);

    style2.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);// 垂直

    HSSFPalette palette = workbook.getCustomPalette();

    HSSFFont font1 = workbook.createFont(); // 设置字体

    if ("自习".equals(sign.getChapterName())) {

    style2.setFillForegroundColor(HSSFColor.LIGHT_YELLOW.index);//设置前景色

    }

    if ("放假".equals(sign.getChapterName())) {

    font1.setColor(IndexedColors.RED.getIndex());

    style2.setFillForegroundColor(HSSFColor.LEMON_CHIFFON.index);

    }

    if ("测试".equals(sign.getChapterName())) {

    style2.setFillForegroundColor(HSSFColor.GREY_40_PERCENT.index);

    }

    if ("补课".equals(sign.getChapterName())) {

    style2.setFillForegroundColor(HSSFColor.LEMON_CHIFFON.index);

    }if("就业指导".equals(sign.getChapterName())){

    style2.setFillForegroundColor(HSSFColor.LAVENDER.index);

    }

    if (sign.getChapterid() > 0) {

    String bgcolor = sign.getBgcolor();

    short colorNum = 0;

    Iterator keys = map.keySet().iterator();

    while (keys.hasNext()) {

    String key = (String) keys.next();

    if (bgcolor.equals(key)) {

    colorNum = map.get(bgcolor);

    break;

    }

    }

    String color = bgcolor.substring(bgcolor.lastIndexOf("#") + 1); // 此处得到的color为16进制的字符串

    // 转为RGB码

    int r = Integer.parseInt((color.substring(0, 2)), 16); // 转为16进制

    int g = Integer.parseInt((color.substring(2, 4)), 16);

    int b = Integer.parseInt((color.substring(4, 6)), 16);

    // 自定义cell颜色

    // 这里的9是索引用来确定的设置颜色的索引只能是 8 ~ 64,在此之外的索引无效,也不会报错。

    palette.setColorAtIndex(colorNum, (byte) r, (byte) g, (byte) b);

    style2.setFillForegroundColor(colorNum);

    }

    style2.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);

    style2.setBorderBottom(HSSFCellStyle.BORDER_THIN); // 下边框

    style2.setBorderLeft(HSSFCellStyle.BORDER_THIN);// 左边框

    style2.setBorderTop(HSSFCellStyle.BORDER_THIN);// 上边框

    style2.setBorderRight(HSSFCellStyle.BORDER_THIN);// 右边框

    font1.setFontHeightInPoints((short) 7);// 设置字体大小

    style2.setFont(font1);

    cell.setCellStyle(style2);// 设置风格

    if ("无".equals(sign.getClassroomname())) {// 赋值

    cell.setCellValue(sign.getChapterName());

    } else {

    cell.setCellValue(sign.getChapterName() + "_" + sign.getClassroomname());

    }

    }

    }

    }

    }

    ByteArrayOutputStream baos = new ByteArrayOutputStream();

    workbook.write(baos);

    excelFile = new ByteArrayInputStream(baos.toByteArray());

    baos.close();

    return "excel";

    展开全文
  • java生成Excel文件 xls

    2010-07-30 09:58:00
    下载问题由于使用jsf框架,本想用jsf方式.但是jsf接触几个月.没系统学过.于是就使用老方法servlet(servlet下载比jsp下载支持的好,比如支持weblogic问题).先生成xls吧 poi官网 http://poi.apache.org/ 上面有poi包...
  • 我使用的是Springboot框架开发的。首先需要在pom.xml文件中引入以下maven包:org.apache.poipoi3.10-FINALorg.apache.poipoi-ooxml3.8然后编写一个excel工具类,使用时直接调用即可。package com.label.tool;import ...
  • java解析、生成Excel比较有名的框架有Apache poi、jxl。但他们都存在一个严重的问题就是非常的耗内存,poi有一套SAX模式的API可以一定程度的解决一些内存溢出的问题,但POI还是有一些缺陷,比如07版Excel解压缩以及...
  • 课程概述:Java解析、生成Excel比较有名的框架有Apache poi、jxl。但他们都存在一个严重的问题就是非常的耗内存,poi有一套SAX模式的API可以一定程度的解决一些内存溢出的问题,但POI还是有一些缺陷,比如07版Excel...
  • 最近发现有一个很厉害的前端框架 js-xlsx ( npm install xlsx ),可以在浏览器端用纯前端的方式生成 Office 的 Excel 格式文件,无需再依赖后端 POI 等库。特此研究对比一下 js-xlsx 与 Java POI 方式生成 Excel ...
  • //使用jxls报表生成工具,把java实体类导出生成 Excel文件或导入 Excel 插入数据库//读取public class ReadExcel {private final static String xmlConfig="student.xml";public List read(){InputStream inputXML =...
  • java项目中,会遇到读取或生成Excel文件的时候,我们来看两个可以实现这一功能的工具包:jxl和poi。 两种方式对比: 1. JXL只能对Excel进行操作,属于比较老的框架,它只支持到Excel 95-2000的版本。现在已经停止...
  • ApachePOI 介绍 需求说明 在企业级应用开发中,...2、通过java代码生成Excel报表。 常见的Excel操作工具 Java中常见的用来操作Excl的方式一般有2种:JXL和POI。 JXL只能对Excel进行操作,属于比较老的框架...
  • POI的介绍 ...而我们Java中,也是提供了相应的操作办公软件的框架,其中,最常用的是下面两种: jxl:只能对Excel进行操作,属于比较老的框架。 POI:是apache的项目,可对ms的word,Excel,PPT进...
  • 二:后端查表 生成excel放到云端 后端开头controller xxxcontroller.java @POST @Path("exportTransExcpOrder") public ResponseBean exportTransExcpOrder() { ResponseBean responseBean = new ResponseBean();...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 495
精华内容 198
关键字:

java生成excel框架

java 订阅