zoukankan      html  css  js  c++  java
  • POI实现Excel导入导出

    利用idea创建java web的maven项目,在pom中添加对poi的jar的依赖。

     1 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     2   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
     3   <modelVersion>4.0.0</modelVersion>
     4   <groupId>com.hand</groupId>
     5   <artifactId>excel-data</artifactId>
     6   <packaging>war</packaging>
     7   <version>1.0-SNAPSHOT</version>
     8   <name>excel-data Maven Webapp</name>
     9   <url>http://maven.apache.org</url>
    10   <dependencies>
    11     <dependency>
    12       <groupId>junit</groupId>
    13       <artifactId>junit</artifactId>
    14       <version>3.8.1</version>
    15       <scope>test</scope>
    16     </dependency>
    17     <dependency>
    18       <groupId>org.apache.poi</groupId>
    19       <artifactId>poi</artifactId>
    20       <version>3.14</version>
    21     </dependency>
    22   </dependencies>
    23   <build>
    24     <finalName>excel-data</finalName>
    25   </build>
    26 </project>

    web.xml中配置下后续导出时,所需要的servlet映射信息:

     1 <!DOCTYPE web-app PUBLIC
     2  "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
     3  "http://java.sun.com/dtd/web-app_2_3.dtd" >
     4 
     5 <web-app>
     6   <display-name>Archetype Created Web Application</display-name>
     7   <servlet>
     8     <servlet-name>TestServlet</servlet-name>
     9     <servlet-class>TestServlet</servlet-class>
    10   </servlet>
    11 
    12   <servlet-mapping>
    13     <servlet-name>TestServlet</servlet-name>
    14     <url-pattern>/TestServlet</url-pattern>
    15   </servlet-mapping>
    16 </web-app>

    Excel导入工具类实现:

      1 import org.apache.poi.hssf.usermodel.*;
      2 import org.apache.poi.poifs.filesystem.POIFSFileSystem;
      3 import java.io.FileInputStream;
      4 import java.io.FileNotFoundException;
      5 import java.io.IOException;
      6 import java.io.InputStream;
      7 import java.text.SimpleDateFormat;
      8 import java.util.Date;
      9 import java.util.HashMap;
     10 import java.util.Map;
     11 
     12 /**
     13  * @author jiaqing.xu@hand-china.com
     14  * @version 1.0
     15  * @name
     16  * @description 读取并解析excel
     17  * @date 2017/10/19
     18  */
     19 public class ImportExcel {
     20 
     21     private POIFSFileSystem fs;
     22     private HSSFWorkbook wb;
     23     private HSSFSheet sheet;
     24     private HSSFRow row;
     25 
     26     /**
     27      * 读取Excel表格表头的内容
     28      * @param is
     29      * @return String 表头内容的数组
     30      */
     31     public String[] readExcelTitle(InputStream is) {
     32         try {
     33             fs = new POIFSFileSystem(is);
     34             wb = new HSSFWorkbook(fs);
     35         } catch (IOException e) {
     36             e.printStackTrace();
     37         }
     38         sheet = wb.getSheetAt(0);
     39         //得到首行的row
     40         row = sheet.getRow(0);
     41         // 标题总列数
     42         int colNum = row.getPhysicalNumberOfCells();
     43         String[] title = new String[colNum];
     44         for (int i = 0; i < colNum; i++) {
     45             title[i] = getCellFormatValue(row.getCell((short) i));
     46         }
     47         return title;
     48     }
     49 
     50     /**
     51      * 读取Excel数据内容
     52      * @param is
     53      * @return Map 包含单元格数据内容的Map对象
     54      */
     55     public Map<Integer, String> readExcelContent(InputStream is) {
     56         Map<Integer, String> content = new HashMap<Integer, String>();
     57         String str = "";
     58         try {
     59             fs = new POIFSFileSystem(is);
     60             wb = new HSSFWorkbook(fs);
     61         } catch (IOException e) {
     62             e.printStackTrace();
     63         }
     64         sheet = wb.getSheetAt(0);
     65         // 得到总行数
     66         int rowNum = sheet.getLastRowNum();
     67         //由于第0行和第一行已经合并了  在这里索引从2开始
     68         row = sheet.getRow(2);
     69         int colNum = row.getPhysicalNumberOfCells();
     70         // 正文内容应该从第二行开始,第一行为表头的标题
     71         for (int i = 2; i <= rowNum; i++) {
     72             row = sheet.getRow(i);
     73             int j = 0;
     74             while (j < colNum) {
     75                 str += getCellFormatValue(row.getCell((short) j)).trim() + "-";
     76                 j++;
     77             }
     78             content.put(i, str);
     79             str = "";
     80         }
     81         return content;
     82     }
     83 
     84     /**
     85      * 获取单元格数据内容为字符串类型的数据
     86      *
     87      * @param cell Excel单元格
     88      * @return String 单元格数据内容
     89      */
     90     private String getStringCellValue(HSSFCell cell) {
     91         String strCell = "";
     92         switch (cell.getCellType()) {
     93             case HSSFCell.CELL_TYPE_STRING:
     94                 strCell = cell.getStringCellValue();
     95                 break;
     96             case HSSFCell.CELL_TYPE_NUMERIC:
     97                 strCell = String.valueOf(cell.getNumericCellValue());
     98                 break;
     99             case HSSFCell.CELL_TYPE_BOOLEAN:
    100                 strCell = String.valueOf(cell.getBooleanCellValue());
    101                 break;
    102             case HSSFCell.CELL_TYPE_BLANK:
    103                 strCell = "";
    104                 break;
    105             default:
    106                 strCell = "";
    107                 break;
    108         }
    109         if (strCell.equals("") || strCell == null) {
    110             return "";
    111         }
    112         if (cell == null) {
    113             return "";
    114         }
    115         return strCell;
    116     }
    117 
    118     /**
    119      * 获取单元格数据内容为日期类型的数据
    120      *
    121      * @param cell
    122      *            Excel单元格
    123      * @return String 单元格数据内容
    124      */
    125     private String getDateCellValue(HSSFCell cell) {
    126         String result = "";
    127         try {
    128             int cellType = cell.getCellType();
    129             if (cellType == HSSFCell.CELL_TYPE_NUMERIC) {
    130                 Date date = cell.getDateCellValue();
    131                 result = (date.getYear() + 1900) + "-" + (date.getMonth() + 1)
    132                         + "-" + date.getDate();
    133             } else if (cellType == HSSFCell.CELL_TYPE_STRING) {
    134                 String date = getStringCellValue(cell);
    135                 result = date.replaceAll("[年月]", "-").replace("日", "").trim();
    136             } else if (cellType == HSSFCell.CELL_TYPE_BLANK) {
    137                 result = "";
    138             }
    139         } catch (Exception e) {
    140             System.out.println("日期格式不正确!");
    141             e.printStackTrace();
    142         }
    143         return result;
    144     }
    145 
    146     /**
    147      * 根据HSSFCell类型设置数据
    148      * @param cell
    149      * @return
    150      */
    151     private String getCellFormatValue(HSSFCell cell) {
    152         String cellvalue = "";
    153         if (cell != null) {
    154             // 判断当前Cell的Type
    155             switch (cell.getCellType()) {
    156                 // 如果当前Cell的Type为NUMERIC
    157                 case HSSFCell.CELL_TYPE_NUMERIC:
    158                 case HSSFCell.CELL_TYPE_FORMULA: {
    159                     // 判断当前的cell是否为Date
    160                     if (HSSFDateUtil.isCellDateFormatted(cell)) {
    161                         Date date = cell.getDateCellValue();
    162                         SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    163                         cellvalue = sdf.format(date);
    164                     }
    165                     // 如果是纯数字
    166                     else {
    167                         // 取得当前Cell的数值
    168                         cellvalue = String.valueOf(cell.getNumericCellValue());
    169                     }
    170                     break;
    171                 }
    172                 // 如果当前Cell的Type为STRIN
    173                 case HSSFCell.CELL_TYPE_STRING:
    174                     // 取得当前的Cell字符串
    175                     cellvalue = cell.getRichStringCellValue().getString();
    176                     break;
    177                 // 默认的Cell值
    178                 default:
    179                     cellvalue = " ";
    180             }
    181         } else {
    182             cellvalue = "";
    183         }
    184         return cellvalue;
    185 
    186     }
    187 
    188     public static void main(String[] args) {
    189         try {
    190             // 对读取Excel表格标题测试
    191             InputStream is = new FileInputStream("d:\test2.xls");
    192             ImportExcel excelReader = new ImportExcel();
    193             String[] title = excelReader.readExcelTitle(is);
    194             System.out.println("获得Excel表格的标题:");
    195             for (String s : title) {
    196                 System.out.print(s + " ");
    197             }
    198             System.out.println();
    199 
    200             // 对读取Excel表格内容测试
    201             InputStream is2 = new FileInputStream("d:\test2.xls");
    202             Map<Integer, String> map = excelReader.readExcelContent(is2);
    203             System.out.println("获得Excel表格的内容:");
    204             //这里由于xls合并了单元格需要对索引特殊处理
    205             for (int i = 2; i <= map.size()+1; i++) {
    206                 System.out.println(map.get(i));
    207             }
    208 
    209         } catch (FileNotFoundException e) {
    210             System.out.println("未找到指定路径的文件!");
    211             e.printStackTrace();
    212         }
    213     }
    214 
    215 }

    将Excel中的数据通过后台程序维护到一个Map集合中,再利用String的split方法以“-”进行分割,得到单个的值,如果想要将这批数据插入到数据库,则去实例化对象的dto,再给dto对应属性赋值,最终写sql再insert到表中。

    Excel导出工具类的实现:

      1 import org.apache.poi.hssf.usermodel.*;
      2 import org.apache.poi.hssf.util.HSSFColor;
      3 import org.apache.poi.ss.usermodel.IndexedColors;
      4 import org.apache.poi.ss.util.CellRangeAddress;
      5
      6 import javax.servlet.http.HttpServletRequest;
      7 import javax.servlet.http.HttpServletResponse;
      8 import java.io.IOException;
      9 import java.io.OutputStream;
     10 import java.util.ArrayList;
     11 import java.util.List;
     12 
     13 /**
     14  * @author jiaqing.xu@hand-china.com
     15  * @version 1.0
     16  * @name
     17  * @description
     18  * @date 2017/10/19
     19  */
     20 public class ExportExcel {
     21 
     22     /**
     23      * 显示的导出表的标题
     24      */
     25     private String title;
     26 
     27     /**
     28      * 导出表的列名
     29      */
     30     private String[] columnName;
     31 
     32     /**
     33      * 需要导出的数据集合
     34      */
     35     private List<Object[]> dataList = new ArrayList<Object[]>();
     36 
     37     /**
     38      * 输入流对象
     39      */
     40     private HttpServletRequest request;
     41 
     42     /**
     43      * 输出流对象
     44      */
     45     private HttpServletResponse response;
     46 
     47 
     48     /**
     49      *
     50      * @param title
     51      * @param columnName
     52      * @param dataList
     53      * @param request
     54      * @param response
     55      * @description 构造方法,传入要导出的数据
     56      */
     57     public ExportExcel(String title, String[] columnName, List<Object[]> dataList,HttpServletRequest request,HttpServletResponse response) {
     58         this.dataList = dataList;
     59         this.columnName = columnName;
     60         this.title = title;
     61         this.request = request;
     62         this.response= response;
     63     }
     64 
     65 
     66     /**
     67      * @param
     68      * @return
     69      * @author jiaqing.xu@hand-china.com
     70      * @date 2017/10/19 13:21
     71      * @description 导出数据到excel
     72      */
     73     public void export() throws Exception {
     74 
     75         try {
     76             HSSFWorkbook workbook = new HSSFWorkbook();                        // 创建工作簿对象
     77             HSSFSheet sheet = workbook.createSheet(title);                     // 创建工作表
     78 
     79             // 产生表格标题行
     80             HSSFRow rowm = sheet.createRow(0);
     81             HSSFCell cellTiltle = rowm.createCell(0);
     82 
     83             //设置标题和单元格样式
     84             HSSFCellStyle columnTopStyle = this.getColumnTopStyle(workbook);  //获取列头样式对象
     85             HSSFCellStyle style = this.getStyle(workbook);                    //单元格样式对象
     86 
     87             //合并单元格
     88             sheet.addMergedRegion(new CellRangeAddress(0, 1, 0, (columnName.length - 1)));
     89             cellTiltle.setCellStyle(columnTopStyle);
     90             cellTiltle.setCellValue(title);
     91 
     92             // 定义所需列数
     93             int columnNum = columnName.length;
     94             HSSFRow rowRowName = sheet.createRow(2);                 // 在索引2的位置创建行(最顶端的行开始的第二行)
     95 
     96 
     97             // 将列头设置到sheet的单元格中
     98             for (int n = 0; n < columnNum; n++) {
     99                 HSSFCell cellRowName = rowRowName.createCell(n);                  //创建列头对应个数的单元格
    100                 cellRowName.setCellType(HSSFCell.CELL_TYPE_STRING);                //设置列头单元格的数据类型
    101                 HSSFRichTextString text = new HSSFRichTextString(columnName[n]);
    102                 cellRowName.setCellValue(text);                                    //设置列头单元格的值
    103                 cellRowName.setCellStyle(columnTopStyle);                          //设置列头单元格样式
    104             }
    105 
    106             //将查询出的数据设置到sheet对应的单元格中
    107             for (int i = 0; i < dataList.size(); i++) {
    108                 Object[] obj = dataList.get(i);//遍历每个对象
    109                 HSSFRow row = sheet.createRow(i + 3);//创建所需的行数
    110                 for (int j = 0; j < obj.length; j++) {
    111                     HSSFCell cell = null;   //设置单元格的数据类型
    112                     //第一列为数字类型并设置单元格的值
    113                     if (j == 0) {
    114                         cell = row.createCell(j, HSSFCell.CELL_TYPE_NUMERIC);
    115                         cell.setCellValue(i + 1);
    116                     } else {
    117                         //其他列为字符串类型并设置单元格的值
    118                         cell = row.createCell(j, HSSFCell.CELL_TYPE_STRING);
    119                         if (!"".equals(obj[j]) && obj[j] != null) {
    120                             cell.setCellValue(obj[j].toString());
    121                         }
    122                     }
    123                     cell.setCellStyle(style);                                    //设置单元格样式
    124                 }
    125             }
    126 
    127 
    128             //让列宽随着导出的列长自动适应
    129             for (int colNum = 0; colNum < columnNum; colNum++) {
    130                 int columnWidth = sheet.getColumnWidth(colNum) / 256;
    131                 for (int rowNum = 0; rowNum < sheet.getLastRowNum(); rowNum++) {
    132                     HSSFRow currentRow;
    133                     //当前行未被使用过
    134                     if (sheet.getRow(rowNum) == null) {
    135                         currentRow = sheet.createRow(rowNum);
    136                     } else {
    137                         currentRow = sheet.getRow(rowNum);
    138                     }
    139                     if (currentRow.getCell(colNum) != null) {
    140                         //取得当前的单元格
    141                         HSSFCell currentCell = currentRow.getCell(colNum);
    142                         //如果当前单元格类型为字符串
    143                         if (currentCell.getCellType() == HSSFCell.CELL_TYPE_STRING) {
    144                             int length = currentCell.getStringCellValue().getBytes().length;
    145                             if (columnWidth < length) {
    146                                 //将单元格里面值大小作为列宽度
    147                                 columnWidth = length;
    148                             }
    149                         }
    150                     }
    151                 }
    152                 //再根据不同列单独做下处理
    153                 if (colNum == 0) {
    154                     sheet.setColumnWidth(colNum, (columnWidth - 2) * 256);
    155                 } else {
    156                     sheet.setColumnWidth(colNum, (columnWidth + 4) * 256);
    157                 }
    158             }
    159 
    160             if (workbook != null) {
    161                 try {
    162                     String fileName = "Excel-" + String.valueOf(System.currentTimeMillis()).substring(4, 13) + ".xls";
    163                     String headStr = "attachment; filename="" + fileName + """;
    164                     response.setContentType("APPLICATION/OCTET-STREAM");
    165                     response.setHeader("Content-Disposition", headStr);
    166                     OutputStream out1 = response.getOutputStream();
    167                     workbook.write(out1);
    168                 } catch (IOException e) {
    169                     e.printStackTrace();
    170                 }
    171             }
    172 
    173         } catch (Exception e) {
    174             e.printStackTrace();
    175         }
    176     }
    177 
    178 
    179     /**
    180      * @param
    181      * @return
    182      * @author jiaqing.xu@hand-china.com
    183      * @date 2017/10/19 13:31
    184      * @description 标题行的单元格样式
    185      */
    186     public HSSFCellStyle getColumnTopStyle(HSSFWorkbook workbook) {
    187 
    188         // 设置字体
    189         HSSFFont font = workbook.createFont();
    190         //设置字体大小
    191         font.setFontHeightInPoints((short) 11);
    192         //字体加粗
    193         font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
    194         //设置字体名字
    195         font.setFontName("Courier New");
    196         //设置样式;
    197         HSSFCellStyle style = workbook.createCellStyle();
    198         style.setFillForegroundColor(IndexedColors.BLUE.getIndex());
    199         //设置底边框;
    200         style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
    201         //设置底边框颜色;
    202         style.setBottomBorderColor(HSSFColor.BLACK.index);
    203         //设置左边框;
    204         style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
    205         //设置左边框颜色;
    206         style.setLeftBorderColor(HSSFColor.BLACK.index);
    207         //设置右边框;
    208         style.setBorderRight(HSSFCellStyle.BORDER_THIN);
    209         //设置右边框颜色;
    210         style.setRightBorderColor(HSSFColor.BLACK.index);
    211         //设置顶边框;
    212         style.setBorderTop(HSSFCellStyle.BORDER_THIN);
    213         //设置顶边框颜色;
    214         style.setTopBorderColor(HSSFColor.BLACK.index);
    215         //在样式用应用设置的字体;
    216         style.setFont(font);
    217         //设置自动换行;
    218         style.setWrapText(false);
    219         //设置水平对齐的样式为居中对齐;
    220         style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
    221         //设置垂直对齐的样式为居中对齐;
    222         style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
    223         return style;
    224     }
    225 
    226     /**
    227      * @param
    228      * @return
    229      * @author jiaqing.xu@hand-china.com
    230      * @date 2017/10/19 13:31
    231      * @description 列数据信息单元格样式
    232      */
    233     public HSSFCellStyle getStyle(HSSFWorkbook workbook) {
    234         // 设置字体
    235         HSSFFont font = workbook.createFont();
    236         //设置字体大小
    237         //font.setFontHeightInPoints((short)10);
    238         //字体加粗
    239         //font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
    240         //设置字体名字
    241         font.setFontName("Courier New");
    242         //设置样式;
    243         HSSFCellStyle style = workbook.createCellStyle();
    244         //设置底边框;
    245         style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
    246         //设置底边框颜色;
    247         style.setBottomBorderColor(HSSFColor.BLACK.index);
    248         //设置左边框;
    249         style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
    250         //设置左边框颜色;
    251         style.setLeftBorderColor(HSSFColor.BLACK.index);
    252         //设置右边框;
    253         style.setBorderRight(HSSFCellStyle.BORDER_THIN);
    254         //设置右边框颜色;
    255         style.setRightBorderColor(HSSFColor.BLACK.index);
    256         //设置顶边框;
    257         style.setBorderTop(HSSFCellStyle.BORDER_THIN);
    258         //设置顶边框颜色;
    259         style.setTopBorderColor(HSSFColor.BLACK.index);
    260         //在样式用应用设置的字体;
    261         style.setFont(font);
    262         //设置自动换行;
    263         style.setWrapText(false);
    264         //设置水平对齐的样式为居中对齐;
    265         style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
    266         //设置垂直对齐的样式为居中对齐;
    267         style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
    268         return style;
    269     }
    270 }

    用于测试导出的Servlet程序:

     1 import javax.servlet.ServletException;
     2 import javax.servlet.annotation.WebServlet;
     3 import javax.servlet.http.HttpServlet;
     4 import javax.servlet.http.HttpServletRequest;
     5 import javax.servlet.http.HttpServletResponse;
     6 import java.io.IOException;
     7 import java.util.ArrayList;
     8 import java.util.List;
     9 
    10 /**
    11  * @author jiaqing.xu@hand-china.com
    12  * @version 1.0
    13  * @name
    14  * @description
    15  * @date 2017/10/19
    16  */
    17 @WebServlet(name = "TestServlet")
    18 public class TestServlet extends HttpServlet {
    19     @Override
    20     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    21         String title = "货运单据导出";
    22         String[] columnName = new String[]{"序号","num1","num2"};
    23         List<Object[]> dataList = new ArrayList<Object[]>();
    24         Object[] objs;
    25         for (int i = 0; i <2; i++) {
    26             objs = new Object[columnName.length];
    27             objs[0] = i;
    28             objs[1] = "1";
    29             objs[2] = "2";
    30             dataList.add(objs);
    31         }
    32         //实例化工具类
    33         ExportExcel ex = new ExportExcel(title, columnName, dataList,request,response);
    34         try {
    35             //导出excel
    36             ex.export();
    37         } catch (Exception e) {
    38             e.printStackTrace();
    39         }
    40     }
    41 
    42     @Override
    43     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    44         doPost(request,response);
    45     }
    46 }

  • 相关阅读:
    Android开发学习总结(一)——搭建最新版本的Android开发环境
    数据库服务器编码,数据库编码,数据库表编码,数据库表字段编码
    webservice(二)简单实例
    webservice(一) 概念
    JAVA的StringBuffer类
    Log4J日志配置详解
    如何配置使用 Log4j
    使用MyBatis Generator自动创建代码
    Spring MVC POST中文乱码解决方案
    JSP开发中对jstl的引用方式(标签库引用)
  • 原文地址:https://www.cnblogs.com/jiaqingshareing/p/7693652.html
Copyright © 2011-2022 走看看