Java導入導出Excel和Word
阿新 • • 發佈:2019-01-30
數據 自定義 cto pdf icc creat extends 代碼 鏈接 ,藍色部分是JSTL標簽庫需要jar包,其他就是處理EXCEL/WORD的jar包
目的
實現Excel/Word導入導出,分以下步驟
- 導入
- 上傳文件
- 解析Excel/Word裏面的內容
- 導出
- 生成Excel/Word文件
- 文件下載
如何實現
- 上傳文件----------Commons FileUpload上傳組件
- Excel/Word-------Apache POI----Apache軟件基金會的開放源碼函式庫,POI提供API給Java程序對Microsoft Office格式檔案讀和寫的功能。
- 下載文件----------ServletOutputStream直接輸出文件流
簡單的demo實現
首先需要這麽幾個jar包,紅色的部分是處理文件上傳需要的jar包
這裏插一段遇到的問題
IDEA將WEB-INF/lib目錄指定為jar目錄,並且將相應的jar包復制過去,但IDEA不提示相關類
解決方案:手動重新導入,更多操作方式看這個貼 https://blog.csdn.net/gdsgdh308227363/article/details/82930321
文件上傳demo
/* * @author MrPeng * @date 2019/1/29 */ @WebServlet("/importExcel") public class ImportExcelServlet extendsHttpServlet { @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //表單上傳到這個Servlet中解析 //判斷表單提交是否存在enctype="multipart/form-data"屬性,也就是有文件流上傳,這種表單getParameter方式是拿不到值的 //需要導入commons-fileupload和commons-io這2個包if (ServletFileUpload.isMultipartContent(request)){ //創建ServletFileUpload對象,默認配置即可 ServletFileUpload upload =new ServletFileUpload(new DiskFileItemFactory()); //設置編碼utf-8 upload.setHeaderEncoding("UTF-8"); try { //從請求中解析出各種表單控件 List<FileItem> fileItemList = upload.parseRequest(request); for (FileItem fileItem:fileItemList){ //判斷是普通表單 if (fileItem.isFormField()){ //獲取表單的name和value System.out.println(fileItem.getFieldName()+‘:‘+fileItem.getString("UTF-8")); }else{ //說明是個文件流 System.out.println(fileItem.getFieldName()); //直接寫到一個文件中--上傳成功 fileItem.write(new File("D:/JavaWeb/ExcelWord/web/upload/"+fileItem.getName())); } } } catch (FileUploadException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } }else{ //request.getParameter("") } } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request,response); } }
處理Excel解析/生成Demo
這裏需要理解一下POI中的類與EXCEL之間的關系
- Excel對象本身對應------------POI中WorkBook類
- Excel中sheet1/2/3對應-------POI中Sheet類
- Excel中每一行對應------------POI中Row類
- Excel中每一個單元格---------POI中Cell類
/**處理EXCEL的類 * @author MrPeng * @date 2019/1/29 */ public class ExcelServiceDemo { /** * 解析excel */ public void impDemo(){ try { //通過工廠方法創建excel對象 Workbook workbook = WorkbookFactory.create(new File("D:/JavaWeb/ExcelWord/web/upload/import_03_excel.xls")); //處理第一個區域默認0開始 Sheet sheet =workbook.getSheetAt(0); //獲取有效數據的最後行數,默認首行從0開始 int rowNum = sheet.getLastRowNum(); //循環遍歷每一行,從第2行開始,第一行是標題 for (int i = 1; i <=rowNum ; i++) { Row row= sheet.getRow(i); //獲取每一行每個單元格的數據,默認也是從開始的,並解析成對應格式的數據 System.out.println("姓名:"+row.getCell(0).getStringCellValue()); System.out.println("年齡:"+row.getCell(1).getNumericCellValue()); System.out.println("時間:"+row.getCell(2).getDateCellValue()); } } catch (IOException e) { e.printStackTrace(); } catch (InvalidFormatException e) { e.printStackTrace(); } } /** * 導出excel * @param isXlsx 是否導出07版 03版後綴為xls ,07版為xlsx * @return */ public void exportDemo(boolean isXlsx) { Workbook workbook = null; if (isXlsx) { //創建07版excel對象 ,07版有些新特性在這個類裏有實現 workbook = new XSSFWorkbook(); } else { //創建03版excel對象 workbook = new HSSFWorkbook(); } //創建工作區域sheet,自定義名字 Sheet sheet = workbook.createSheet("My Sheet"); //模擬假數據建一個getContent()方法獲取一個二維MAP數組 List<List<String>> content = this.getContent(); //外層循環控制行 for (int i = 0; i < content.size(); i++) { //創建一行 Row row = sheet.createRow(i); List<String> rowData = content.get(i); //內層循環控制每個單元格 for (int j = 0; j < rowData.size(); j++) { //創建單元格,並設置值 row.createCell(j).setCellValue(rowData.get(j)); } } FileOutputStream fileOutputStream = null; try { fileOutputStream = new FileOutputStream("D:\\JavaWeb\\ExcelWord\\web\\upload\\demo-07.xlsx"); } catch (FileNotFoundException e) { e.printStackTrace(); } //先將excel對象保存到文件輸出流--可以不保留文件 //workbook.write(outputStream);//也就是直接寫入ServletOutputStream輸出流對象中 try { workbook.write(fileOutputStream); } catch (IOException e) { e.printStackTrace(); }finally { try { workbook.close(); } catch (IOException e) { e.printStackTrace(); } } } }
處理Word解析生成Demo
/**Word解析生成Demo * @author MrPeng * @date 2019/1/29 */ public class WordServiceDemo { /** * 解析03Word, 由於03和07差異較大 實際處理策略是先用03的解析 在用07的解析 */ public void imp03() { HWPFDocument doc = null; //嘗試03版的解析 try { //創建對象--文件流方式 如果需要保存文件,則可以使用File對象創建 doc = new HWPFDocument(new FileInputStream("D:/JavaWeb/ExcelWord/web/upload/import_03_word.doc")); //直接獲取doc中的文本信息,如果是原樣一般是轉PDF String text = doc.getDocumentText(); //替換成html中的換行 text=text.replace("\r","<br/>"); //輸出解析的文本 System.out.println(text); } catch (OfficeXmlFileException oe) { //版本可能不對 System.out.println("這可能是一個07版的Word"); } catch (Exception e) { //解析錯誤 e.printStackTrace(); } finally { //釋放資源 if(doc != null) { try { doc.close(); } catch (IOException e) { e.printStackTrace(); } } } } /** * 解析07版 */ public void imp07() { XWPFDocument docx = null; try { //創建07版Word對象--文件流方式 docx = new XWPFDocument(new FileInputStream("D:/JavaWeb/ExcelWord/web/upload/import_07_word.doc")); //從每一個段落取文本--當文字出現換行符認為是一個段落 List<XWPFParagraph> paragraphList = docx.getParagraphs(); StringBuilder content = new StringBuilder(); for (int i = 0; i < paragraphList.size(); i++) { //換行處理 if(i != 0) { content.append("<br/>"); } content.append(paragraphList.get(i).getText()); } //輸出文本 System.out.println(content.toString()); } catch (IOException e) { //解析錯誤 e.printStackTrace(); } finally { if(docx != null) { try { docx.close(); } catch (IOException e) { e.printStackTrace(); } } } } /** * 導出03版Word * @param replaceContent--需要替換的東西k-v * @return */ public HWPFDocument export03(Map<String,String> replaceContent) { HWPFDocument doc = null; try { //創建03Word對象 doc = new HWPFDocument(new FileInputStream("D:\\JavaWeb\\ExcelWord\\web\\template\\template_03.doc")); //獲取Word文檔範圍 Range range = doc.getRange(); //替換模板中的變量 for(Map.Entry<String,String> entry : replaceContent.entrySet()) { range.replaceText(entry.getKey(),entry.getValue()); } } catch (Exception e) { //這裏不能有finally關閉doc,否則servlet不能將其寫入response響應流 return null; } //返回doc對象,可以選擇像之前的excel導出處理 是否保留文件 return doc; } /** * 導出07版Word * @param replaceContent--需要替換的東西k-v * @return */ public XWPFDocument export07(Map<String,String> replaceContent) { XWPFDocument docx = null; try { //創建07版WORD對象 docx = new XWPFDocument(new FileInputStream("D:\\JavaWeb\\ExcelWord\\web\\template\\template_07.docx")); //獲取每一個段落 List<XWPFParagraph> paragraphList = docx.getParagraphs(); for(XWPFParagraph paragraph : paragraphList) { //07版段落還不是最小單位,遇到不同樣式或者格式的文本也可能再拆分 List<XWPFRun> runs = paragraph.getRuns(); for(XWPFRun run : runs) { //獲取最小單元的文本 String str = run.getText(run.getTextPosition()); //將key替換成value for(Map.Entry<String,String> entry : replaceContent.entrySet()) { str = str.replace(entry.getKey(),entry.getValue()); } //直接賦值回去 run.setText(str,0); } } } catch (IOException e) { return null; } return docx; } }
最後附上完整代碼
一個實現上訴操作的建議Web應用
鏈接:https://pan.baidu.com/s/1al8_ux3LF6SJtBfXz4Z4-Q
提取碼:u3a6
Java導入導出Excel和Word