POI實現Excel導入導出

利用idea建立java web的maven項目,在pom中添加對poi的jar的依賴。java

 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映射信息:web

 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導入工具類實現:sql

  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導出工具類的實現:apache

  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 }

相關文章
相關標籤/搜索