1.1.添加上传必要jar包
<dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.4</version> </dependency> <dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3.1</version> </dependency>
1.2.springmvc xml配置
1 <!-- SpringMVC上传文件时,需要配置MultipartResolver处理器 -->2 <bean id="multipartResolver"3 class="org.springframework.web.multipart.commons.CommonsMultipartResolver">4 <property name="defaultEncoding" value="UTF-8" />5 <!-- 指定所上传文件的总大小,单位字节。注意maxUploadSize属性的限制不是针对单个文件,而是所有文件的容量之和 -->6 <property name="maxUploadSize" value="10240000" />7 </bean>
注意不论是上传 图片还是 doc文档等,前端写法都一样,只是后端解析工具类不一样而已
1 <%@ page contentType="text/html;charset=UTF-8" language="java" %> 2 <html> 3 <head> 4 <title>ajax请求上传文件</title> 5 <script type="text/javascript" src="/static/js/jquery.min.js"></script> 6 </head> 7 <body> 8 <%--页面按钮--%> 9 <button id="addImport">导入</button> 10 <%--隐藏的文件输入框--%> 11 <input id="FileUpload" name="file" type="file" onchange="uploadWord()" style="display: none"/> 12 </body> 13 <script type="text/javascript"> 14 /** 15 * 导入word文档入口 16 */ 17 $(‘#addImport‘).click(function () { 18 openFileDialogue(); 19 }); 20 /** 21 * 打开上传文件对话框 22 */ 23 function openFileDialogue() { 24 var f = document.getElementById(‘FileUpload‘); 25 f.click(); 26 } 27 28 /** 29 * 文件上传 前检查与确认 30 */ 31 var msg; 32 function uploadWord() { 33 var fileObj = document.getElementById("FileUpload").files[0]; // js 获取文件对象 34 var fileObjName = $("#FileUpload").val(); 35 if (typeof (fileObj) == "undefined" || fileObj.size <= 0) { 36 alert("请选择要导入的文档?"); 37 return; 38 } 39 //判断是否为 doc 或 docx 文件 40 var fileName = getFileName(fileObjName); 41 var fileSuffix = getFileSuffix(fileObjName); 42 if (fileSuffix != ‘doc‘ && fileSuffix != ‘docx‘) { 43 alert("----请选择正确的文件格式---------"); 44 return; 45 } 46 //确认是否上传(略) 47 //执行上传 48 uploadWordDo(fileObj, fileName); 49 50 } 51 52 /** 53 * 发送ajax请求 执行上传 54 */ 55 function uploadWordDo(fileObj) { 56 var formFile = new FormData(); 57 formFile.append("file", fileObj); //加入文件对象 58 formFile.append("basePath", ""); //加入文件对象 59 var data = formFile; 60 $.ajax({ 61 url: "/upload/do", 62 data: data, 63 type: "Post", 64 dataType: "json", 65 async: true, 66 cache: false, 67 processData: false,//用于对data参数进行序列化处理 这里必须false 68 contentType: false, //必须 69 success: function (result) { 70 //成功提示 71 var code = result.code; 72 if (code == ‘0000‘) { 73 alert("--上传成功---"); 74 } else { 75 alert("--失败---"); 76 } 77 } 78 }); 79 } 80 /** 81 * 获取文件名 82 * @param file 83 * @returns {*} 84 */ 85 function getFileName(file) { 86 var arr = file.split(‘\\‘); 87 return arr[arr.length - 1]; 88 } 89 90 /** 91 * 获取后缀 92 * @param file 93 * @returns {string} 94 */ 95 function getFileSuffix(file) { 96 var point = file.lastIndexOf("."); 97 var type = file.substr(point + 1); 98 return type; 99 }100 101 </script>102 </html>
View Code
后端controller主要有两个方法,一个是获取上传页面的方法,另一个是处理上传的方法
1 package com.linrain.jcs.controller.bbsNews; 2 3 import com.alibaba.fastjson.JSONObject; 4 import com.linrain.jcs.constant.CommonConstant; 5 import com.linrain.jcs.tool.DateUtil; 6 import com.linrain.jcs.tool.downPOI.baseDown.PoiUtil; 7 import org.springframework.stereotype.Controller; 8 import org.springframework.web.bind.annotation.RequestMapping; 9 import org.springframework.web.bind.annotation.RequestMethod;10 import org.springframework.web.bind.annotation.RequestParam;11 import org.springframework.web.bind.annotation.ResponseBody;12 import org.springframework.web.multipart.MultipartFile;13 14 import javax.servlet.http.HttpServletRequest;15 import java.io.InputStream;16 17 /**18 * 文件上传19 * Created by 姿势帝 on 2018/7/20.20 * WX: 85129834821 */22 @Controller23 @RequestMapping(value = "/upload")24 public class UploadController {25 26 /**27 * 文件上传页面28 *29 * @return30 */31 @RequestMapping(value = "/page")32 public String page() {33 34 return "bbsNews/upload";35 }36 37 /**38 * 上传doc 或 docx39 *40 * @param file41 * @return42 */43 @RequestMapping(value = "/do", method = RequestMethod.POST)44 @ResponseBody45 public Object doUploadFile(@RequestParam("file") MultipartFile file, HttpServletRequest request, String basePath) {46 JSONObject jsonObject = new JSONObject();47 if (!file.isEmpty()) {48 try {49 InputStream inputStream = file.getInputStream();50 String originalFilename = file.getOriginalFilename();51 String fileName = DateUtil.getTimeString() + originalFilename;52 //文件处理工具类(以后什么文件,这里就调用什么处理工具就可以了,这里是将上传的doc文件转变为html文件)53 String con = PoiUtil.getHtml(inputStream, fileName);54 jsonObject.put("content", con);55 jsonObject.put("success", true);56 jsonObject.put("code", CommonConstant.CODE_SUCCESS);57 return jsonObject;58 } catch (Exception e) {59 e.printStackTrace();60 61 }62 }63 jsonObject.put("success", false);64 jsonObject.put("code", CommonConstant.CODE_IMPORT_FALSE);65 jsonObject.put("msg", "文档导入失败!");66 return jsonObject;67 }68 }
View Code
该工具类中主要处理 将doc或docx转变为--html文件
1 package com.linrain.jcs.tool.downPOI.baseDown; 2 3 /** 4 * Created by Administrator on 2018/11/29. 5 */ 6 7 import com.linrain.jcs.tool.ConfigUtil; 8 import org.apache.poi.hwpf.HWPFDocument; 9 import org.apache.poi.hwpf.converter.PicturesManager; 10 import org.apache.poi.hwpf.converter.WordToHtmlConverter; 11 import org.apache.poi.hwpf.usermodel.PictureType; 12 import org.apache.poi.xwpf.converter.core.BasicURIResolver; 13 import org.apache.poi.xwpf.converter.core.FileImageExtractor; 14 import org.apache.poi.xwpf.converter.xhtml.XHTMLConverter; 15 import org.apache.poi.xwpf.converter.xhtml.XHTMLOptions; 16 import org.apache.poi.xwpf.usermodel.XWPFDocument; 17 import org.slf4j.Logger; 18 import org.slf4j.LoggerFactory; 19 import org.w3c.dom.Document; 20 21 import javax.xml.parsers.DocumentBuilderFactory; 22 import javax.xml.transform.OutputKeys; 23 import javax.xml.transform.Transformer; 24 import javax.xml.transform.TransformerFactory; 25 import javax.xml.transform.dom.DOMSource; 26 import javax.xml.transform.stream.StreamResult; 27 import java.io.*; 28 import java.util.UUID; 29 30 /** 31 * Created by 姿势帝 on 2018/11/299. 32 * 使用poi将word转为html文件,并从文件中读取内容 33 * wx:851298348 34 */ 35 public class PoiUtil { 36 private static final Logger log = LoggerFactory.getLogger(PoiUtil.class); 37 // 在html中图片保存的相对路径 static/images/upload 38 // private static String imagePath = "\\static\\images\\upload\\"; 39 private static String imagePath = ConfigUtil.getTempImagePath(); 40 private static String imagePathStr; //图片绝对地址 41 public static String rootPath;//项目跟路径 42 public static Long tempTime;//项目跟路径 43 44 /** 45 * 初始换图片地址 46 */ 47 static { 48 RegexAnswerUtil regexAnswerUtil = new RegexAnswerUtil(); 49 rootPath = regexAnswerUtil.getRootPath(); 50 imagePathStr = rootPath + imagePath; 51 log.info(" imagePathStr = " + imagePathStr); 52 tempTime = ConfigUtil.getTempTime(); 53 } 54 55 /** 56 * 更具文件名称判断是否超时 57 */ 58 public static boolean haveOvertime(String fileName) { 59 boolean flag = false; 60 if (fileName == null || fileName.length() < 14) { 61 return flag; 62 } 63 try { 64 String substring = fileName.substring(0, 13); 65 Long fileTime = Long.valueOf(substring); 66 Long nowTime = System.currentTimeMillis(); 67 long l = nowTime - fileTime; 68 // long time = 2 * 60 * 60 * 1000; // 2个小时 69 //long time = 2 * 60 * 1000; // 2 分钟 70 if (l > tempTime) { 71 flag = true; 72 } 73 } catch (Exception e) { 74 e.printStackTrace(); 75 } 76 return flag; 77 } 78 79 /** 80 * 删除文件 81 */ 82 public static void del() { 83 File file = new File(imagePathStr); 84 delete(file); 85 } 86 87 /** 88 * 根据地址删除文件 89 * 90 * @param path 91 */ 92 public static void deletePic(String path) { 93 File file = new File(path); 94 boolean delete = file.delete(); 95 log.info(" delete=" + delete + "path=" + path); 96 } 97 98 public static String getTimeUUID() { 99 String s = UUID.randomUUID().toString();100 s = s.substring(0, 4);101 return System.currentTimeMillis() + "-word" + s;102 }103 104 /**105 * 根据文件递归删除106 *107 * @param file108 */109 public static void delete(File file) {110 if (!file.exists()) return;111 if (file.isFile() || file.list() == null) {112 String path = file.getPath();113 String name = file.getName();114 if (haveOvertime(name)) {115 boolean delete = file.delete();116 log.info("delete=" + delete + " path=" + path);117 } else {118 log.info("该文不符合删除条件 path=" + path);119 }120 121 } else {122 File[] files = file.listFiles();123 for (File a : files) {124 delete(a);125 }126 boolean delete = file.delete();127 log.info("删除文件夹 delete =" + delete + " path=" + file.getPath());128 }129 }130 131 /**132 * @param inputStream word文件的File对象133 * @param sourceFileName word文件名134 * @return 转成的html字符串135 */136 public static String getHtml(InputStream inputStream, String sourceFileName) throws Exception {137 String content;138 // 判断word文档类型,使用不同方法进行转换139 if (sourceFileName.endsWith(".doc")) {140 content = docToHtml(inputStream, sourceFileName);141 } else if (sourceFileName.endsWith(".docx")) {142 content = docxToHtml(inputStream, sourceFileName);143 } else {144 return "文件类型错误";145 }146 // 利用正则表达式过滤无用标签和属性147 // content = RegexAnswerUtil.clear(content);148 return content;149 }150 151 152 /**153 * 将doc文件转变为html154 *155 * @param fileInputStream156 * @param sourceFileName157 * @return158 * @throws Exception159 */160 public static String docToHtml(InputStream fileInputStream, String sourceFileName) throws Exception {161 String targetFileName = imagePathStr + sourceFileName.substring(0, sourceFileName.lastIndexOf(".")) + ".html";162 HWPFDocument wordDocument = new HWPFDocument(fileInputStream);163 Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();164 WordToHtmlConverter wordToHtmlConverter = new WordToHtmlConverter(document);165 // 保存图片,并返回图片的相对路径166 wordToHtmlConverter.setPicturesManager(new PicturesManager() {167 @Override168 public String savePicture(byte[] content, PictureType pictureType, String name, float width, float height) {169 name = getTimeUUID() + name;170 try (FileOutputStream out = new FileOutputStream(new File(imagePathStr + name))) {171 out.write(content);172 } catch (Exception e) {173 e.printStackTrace();174 }175 return imagePath + "\\" + name;176 }177 });178 179 /*wordToHtmlConverter.setPicturesManager((content, pictureType, name, width, height) -> {180 // name = DateUtil.getTimeString() + name;181 name = getTimeUUID() + name;182 try (FileOutputStream out = new FileOutputStream(new File(imagePathStr + name))) {183 out.write(content);184 } catch (Exception e) {185 e.printStackTrace();186 }187 return imagePath + "\\" + name;188 });*/189 wordToHtmlConverter.processDocument(wordDocument);190 Document htmlDocument = wordToHtmlConverter.getDocument();191 DOMSource domSource = new DOMSource(htmlDocument);192 StreamResult streamResult = new StreamResult(new File(targetFileName));193 TransformerFactory tf = TransformerFactory.newInstance();194 Transformer serializer = tf.newTransformer();195 serializer.setOutputProperty(OutputKeys.ENCODING, "utf-8");196 serializer.setOutputProperty(OutputKeys.INDENT, "yes");197 serializer.setOutputProperty(OutputKeys.METHOD, "html");198 serializer.transform(domSource, streamResult);199 String content = splitContext(targetFileName);200 // 删除生成的html文件201 File file = new File(targetFileName);202 // file.delete();203 System.out.println("content= " + content);204 return content;205 }206 207 /**208 * docx转换为html209 *210 * @param inputStream211 * @param sourceFileName212 * @return213 * @throws Exception214 */215 public static String docxToHtml(InputStream inputStream, String sourceFileName) throws Exception {216 String targetFileName = imagePathStr + sourceFileName.substring(0, sourceFileName.lastIndexOf(".")) + ".html";217 File target = new File(targetFileName);218 target.getParentFile().mkdirs();219 OutputStreamWriter outputStreamWriter = null;220 try {221 XWPFDocument document = new XWPFDocument(inputStream);222 XHTMLOptions options = XHTMLOptions.create();223 // 存放图片的文件夹224 options.setExtractor(new FileImageExtractor(new File(imagePathStr)));225 // html中图片的路径226 options.URIResolver(new BasicURIResolver(imagePath));227 outputStreamWriter = new OutputStreamWriter(new FileOutputStream(target), "utf-8");228 XHTMLConverter xhtmlConverter = (XHTMLConverter) XHTMLConverter.getInstance();229 xhtmlConverter.convert(document, outputStreamWriter, options);230 } finally {231 if (outputStreamWriter != null) {232 outputStreamWriter.close();233 }234 }235 String content = splitContext(targetFileName);236 // 删除生成的html文件237 File file = new File(targetFileName);238 file.delete();239 // System.out.println(" content docx= " + content);240 return content;241 }242 243 /**244 * 读取转换得到的html文件,并过滤多余空行245 */246 public static String splitContext(String filePath) {247 File file = new File(filePath);248 BufferedReader reader = null;249 try {250 InputStreamReader isr = new InputStreamReader(new FileInputStream(file), "UTF-8");251 reader = new BufferedReader(isr);252 StringBuilder sb = new StringBuilder();253 String tempString = null;254 // 一次读入一行,直到读入null为文件结束255 while ((tempString = reader.readLine()) != null) {256 sb.append(tempString);257 if (!"".equals(tempString)) {258 sb.append("\n");259 }260 }261 reader.close();262 String content = sb.toString().replaceAll("\\n+", "\n");263 return content;264 } catch (IOException e) {265 e.printStackTrace();266 } finally {267 if (reader != null) {268 try {269 reader.close();270 } catch (IOException e1) {271 }272 }273 }274 return "";275 }276 }
View Code
5.1.页面效果
5.2.点击导入按钮
5.3.导入成功提示
注意:本文中主要讲解上传流程和逻辑,实际生产中需要根据产品要求给出友好提示,如文件类型限制,上传前提醒用户使用上传该文件等友好提示
完美!