目的
实现Excel/Word导入导出,分以下步骤
- 导入
- 上传文件
- 解析Excel/Word里面的内容
- 导出
- 生成Excel/Word文件
- 文件下载
如何实现
- 上传文件----------Commons FileUpload上传组件
- Excel/Word-------Apache POI----Apache软件基金会的开放源码函式库,POI提供API给Java程序对Microsoft Office格式档案读和写的功能。
- 下载文件----------ServletOutputStream直接输出文件流
简单的demo实现
首先需要这么几个jar包,红色的部分是处理文件上传需要的jar包,蓝色部分是JSTL标签库需要jar包,其他就是处理EXCEL/WORD的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 extends HttpServlet { @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
原文地址:https://www.cnblogs.com/phperpxy/p/10335913.html
时间: 2024-11-08 04:12:14