当前位置:   article > 正文

SSM实现Excel的导入导出功能_ssm中如何把服务器的excel文件以输出流方式返回到前端

ssm中如何把服务器的excel文件以输出流方式返回到前端

需要的jar包

  1. <dependency>
  2. <groupId>org.apache.poi</groupId>
  3. <artifactId>poi</artifactId>
  4. <version>3.14</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.apache.poi</groupId>
  8. <artifactId>poi-ooxml-schemas</artifactId>
  9. <version>3.14</version>
  10. </dependency>
  11. <dependency>
  12. <groupId>org.apache.poi</groupId>
  13. <artifactId>poi-ooxml</artifactId>
  14. <version>3.14</version>
  15. </dependency>
  16. <dependency>
  17. <groupId>org.apache.httpcomponents</groupId>
  18. <artifactId>httpclient</artifactId>
  19. <version>4.5.2</version>
  20. </dependency>

工具类

  1. public class ExcelUtil {
  2. private final static String excel2003L =".xls"; //2003- 版本的excel
  3. private final static String excel2007U =".xlsx"; //2007+ 版本的excel
  4. /**
  5. * 描述:获取IO流中的数据,组装成List<List<Object>>对象
  6. * @param in,fileName
  7. * @return
  8. * @throws
  9. */
  10. public List<List<Object>> getBankListByExcel(InputStream in,String fileName) throws Exception{
  11. List<List<Object>> list = null;
  12. //创建Excel工作薄
  13. Workbook work = this.getWorkbook(in,fileName);
  14. if(null == work){
  15. throw new Exception("创建Excel工作薄为空!");
  16. }
  17. Sheet sheet = null; //页数
  18. Row row = null; //行数
  19. Cell cell = null; //列数
  20. list = new ArrayList<List<Object>>();
  21. //遍历Excel中所有的sheet
  22. // 将最大的列数记录下来
  23. int lastCellNum = 0;
  24. for (int i = 0; i < work.getNumberOfSheets(); i++) {
  25. sheet = work.getSheetAt(i);
  26. if(sheet==null){continue;}
  27. //遍历当前sheet中的所有行
  28. for (int j = sheet.getFirstRowNum(); j <= sheet.getLastRowNum(); j++) {
  29. row = sheet.getRow(j);
  30. if(row==null){continue;}
  31. //遍历所有的列
  32. List<Object> li = new ArrayList<Object>();
  33. // 比较当前行的列数跟表的最大的列数
  34. if (j == sheet.getFirstRowNum()) {
  35. // 将第一行的列数设为最大
  36. lastCellNum = row.getLastCellNum();
  37. }else {
  38. lastCellNum = lastCellNum > row.getLastCellNum() ? lastCellNum : row.getLastCellNum();
  39. }
  40. for (int y = row.getFirstCellNum(); y < lastCellNum; y++) {
  41. cell = row.getCell(y);
  42. li.add(this.getValue(cell));
  43. }
  44. System.out.println(list.toString());
  45. list.add(li);
  46. }
  47. }
  48. return list;
  49. }
  50. /**
  51. * 描述:根据文件后缀,自适应上传文件的版本
  52. * @param inStr,fileName
  53. * @return
  54. * @throws Exception
  55. */
  56. public Workbook getWorkbook(InputStream inStr,String fileName) throws Exception{
  57. Workbook wb = null;
  58. String fileType = fileName.substring(fileName.lastIndexOf("."));
  59. if(excel2003L.equals(fileType)){
  60. wb = new HSSFWorkbook(inStr); //2003-
  61. }else if(excel2007U.equals(fileType)){
  62. wb = new XSSFWorkbook(inStr); //2007+
  63. }else{
  64. throw new Exception("解析的文件格式有误!");
  65. }
  66. return wb;
  67. }
  68. /**
  69. * 描述:对表格中数值进行格式化
  70. * @param cell
  71. * @return
  72. */
  73. //解决excel类型问题,获得数值
  74. public String getValue(Cell cell) {
  75. String value = "";
  76. if(null==cell){
  77. return value;
  78. }
  79. switch (cell.getCellType()) {
  80. //数值型
  81. case Cell.CELL_TYPE_NUMERIC:
  82. if (HSSFDateUtil.isCellDateFormatted(cell)) {
  83. //如果是date类型则 ,获取该cell的date值
  84. Date date = HSSFDateUtil.getJavaDate(cell.getNumericCellValue());
  85. // 根据自己的实际情况,excel表中的时间格式是yyyy-MM-dd HH:mm:ss还是yyyy-MM-dd,或者其他类型
  86. SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  87. // 由于方法的返回值类型为String,这里将Date类型转为String,便于统一返回数据
  88. value = format.format(date);;
  89. }else {// 纯数字
  90. BigDecimal big=new BigDecimal(cell.getNumericCellValue());
  91. value = big.toString();
  92. //解决1234.0 去掉后面的.0
  93. if(null!=value&&!"".equals(value.trim())){
  94. String[] item = value.split("[.]");
  95. if(1<item.length&&"0".equals(item[1])){
  96. value=item[0];
  97. }
  98. }
  99. }
  100. break;
  101. //字符串类型
  102. case Cell.CELL_TYPE_STRING:
  103. value = cell.getStringCellValue().toString();
  104. break;
  105. // 公式类型
  106. case Cell.CELL_TYPE_FORMULA:
  107. //读公式计算值
  108. value = String.valueOf(cell.getNumericCellValue());
  109. if (value.equals("NaN")) {// 如果获取的数据值为非法值,则转换为获取字符串
  110. value = cell.getStringCellValue().toString();
  111. }
  112. break;
  113. // 布尔类型
  114. case Cell.CELL_TYPE_BOOLEAN:
  115. value = " "+ cell.getBooleanCellValue();
  116. break;
  117. default:
  118. value = cell.getStringCellValue().toString();
  119. }
  120. if("null".endsWith(value.trim())){
  121. value="";
  122. }
  123. return value;
  124. }
  125. /**
  126. * 导出Excel表
  127. * @param clazz 数据源model类型
  128. * @param objs excel标题以及对应的model字段
  129. * @param map 标题行数以及cell字体样式
  130. * @param sheetName 工作簿名称
  131. * @return
  132. */
  133. public static XSSFWorkbook createExcelFile(
  134. Class<?> clazz,
  135. List<Map<String,Object>> objs,
  136. Map<Integer,List<ExcelBean>> map,
  137. String sheetName) throws Exception{
  138. //创建新的工作簿
  139. XSSFWorkbook workbook = new XSSFWorkbook();
  140. //创建工作表
  141. XSSFSheet sheet = workbook.createSheet(sheetName);
  142. //设置excel的字体样式以及标题与内容的创建
  143. createFont(workbook);//字体样式
  144. createTableHeader(sheet,map);//创建标题
  145. createTableRows(sheet,map,objs,clazz);//创建内容
  146. System.out.println(workbook);
  147. return workbook;
  148. }
  149. private static XSSFCellStyle fontStyle;
  150. private static XSSFCellStyle fontStyle2;
  151. private static void createFont(XSSFWorkbook workbook) {
  152. //表头
  153. fontStyle = workbook.createCellStyle();
  154. XSSFFont font1 = workbook.createFont();
  155. font1.setBoldweight(XSSFFont.BOLDWEIGHT_BOLD);
  156. font1.setFontName("黑体");
  157. font1.setFontHeightInPoints((short) 12);//字体大小
  158. fontStyle.setFont(font1);
  159. fontStyle.setBorderBottom(XSSFCellStyle.BORDER_THIN);//下边框
  160. fontStyle.setBorderLeft(XSSFCellStyle.BORDER_THIN);//左边框
  161. fontStyle.setBorderTop(XSSFCellStyle.BORDER_THIN);//右边框
  162. fontStyle.setBorderRight(XSSFCellStyle.BORDER_THIN);//右边框
  163. fontStyle.setAlignment(XSSFCellStyle.ALIGN_CENTER);//居中
  164. //内容
  165. fontStyle2 = workbook.createCellStyle();
  166. XSSFFont font2 = workbook.createFont();
  167. font2.setFontName("宋体");
  168. font2.setFontHeightInPoints((short)10);
  169. fontStyle2.setFont(font2);
  170. fontStyle2.setBorderBottom(XSSFCellStyle.BORDER_THIN);//下边框
  171. fontStyle2.setBorderLeft(XSSFCellStyle.BORDER_THIN);//左边框
  172. fontStyle2.setBorderTop(XSSFCellStyle.BORDER_THIN);//右边框
  173. fontStyle2.setBorderRight(XSSFCellStyle.BORDER_THIN);//右边框
  174. fontStyle2.setAlignment(XSSFCellStyle.ALIGN_CENTER);//居中
  175. }
  176. /**
  177. * 根据ExcelMapping 生成列头(多行列头)
  178. * @param sheet 工作簿
  179. * @param map 每行每个单元格对应的列头信息
  180. */
  181. private static void createTableHeader(
  182. XSSFSheet sheet,
  183. Map<Integer, List<ExcelBean>> map) {
  184. int startIndex = 0;//cell起始位置
  185. int endIndex = 0;//cell终止位置
  186. for(Map.Entry<Integer,List<ExcelBean>> entry: map.entrySet()){
  187. XSSFRow row = sheet.createRow(entry.getKey()); //创建行
  188. List<ExcelBean> excels = entry.getValue();
  189. for(int x=0;x<excels.size();x++){
  190. //合并单元格
  191. if(excels.get(x).getCols()>1){
  192. if(x==0){
  193. endIndex += excels.get(x).getCols()-1;
  194. //合并单元格CellRangeAddress构造参数依次表示起始行,截至行,起始列, 截至列
  195. sheet.addMergedRegion(new CellRangeAddress(0, 0, startIndex, endIndex));
  196. startIndex += excels.get(x).getCols();
  197. }else{
  198. endIndex += excels.get(x).getCols();
  199. sheet.addMergedRegion(new CellRangeAddress(0, 0, startIndex, endIndex));
  200. startIndex += excels.get(x).getCols();
  201. }
  202. XSSFCell cell = row.createCell(startIndex-excels.get(x).getCols());
  203. //设置内容
  204. cell.setCellValue(excels.get(x).getHeadTextName());
  205. if(excels.get(x).getCellStyle() != null){
  206. //设置格式
  207. cell.setCellStyle(excels.get(x).getCellStyle());
  208. }
  209. cell.setCellStyle(fontStyle);
  210. }else{
  211. XSSFCell cell = row.createCell(x);
  212. //设置内容
  213. cell.setCellValue(excels.get(x).getHeadTextName());
  214. if(excels.get(x).getCellStyle() != null){
  215. //设置格式
  216. cell.setCellStyle(excels.get(x).getCellStyle());
  217. }
  218. cell.setCellStyle(fontStyle);
  219. }
  220. }
  221. }
  222. }
  223. /**
  224. * 为excel表中循环添加数据
  225. * @param sheet
  226. * @param map 字段名
  227. * @param objs 查询的数据
  228. * @param clazz 无用
  229. */
  230. private static void createTableRows(
  231. XSSFSheet sheet,
  232. Map<Integer,List<ExcelBean>> map,
  233. List<Map<String,Object>> objs,
  234. Class<?> clazz)
  235. throws Exception{
  236. int rowindex = map.size();
  237. int maxkey = 0;
  238. List<ExcelBean> ems = new ArrayList<ExcelBean>();
  239. for(Map.Entry<Integer,List<ExcelBean>> entry : map.entrySet()){
  240. if(entry.getKey() > maxkey){
  241. maxkey = entry.getKey();
  242. }
  243. }
  244. ems = map.get(maxkey);
  245. List<Integer> widths = new ArrayList<Integer>(ems.size());
  246. for(Map<String,Object> obj : objs){
  247. XSSFRow row = sheet.createRow(rowindex);
  248. for(int i=0;i<ems.size();i++){
  249. ExcelBean em = (ExcelBean)ems.get(i);
  250. String propertyName = em.getPropertyName();
  251. Object value = obj.get(propertyName);
  252. XSSFCell cell = row.createCell(i);
  253. String cellValue = "";
  254. if("valid".equals(propertyName)){
  255. cellValue = value.equals(1)?"启用":"禁用";
  256. }else if(value==null){
  257. cellValue = "";
  258. }else if(value instanceof Date){
  259. cellValue = new SimpleDateFormat("yyyy-MM-dd HH:mm").format(value);
  260. }else{
  261. cellValue = value.toString();
  262. }
  263. cell.setCellValue(cellValue);
  264. cell.setCellType(XSSFCell.CELL_TYPE_STRING);
  265. cell.setCellStyle(fontStyle2);
  266. sheet.autoSizeColumn(i);
  267. }
  268. rowindex++;
  269. }
  270. //设置列宽
  271. for(int index=0;index<widths.size();index++){
  272. Integer width = widths.get(index);
  273. width = width<2500?2500:width+300;
  274. width = width>10000?10000+300:width+300;
  275. sheet.setColumnWidth(index, width);
  276. }
  277. }
  278. }

service接口

  1. public interface ExcelService {
  2. /**
  3. * 导入excel
  4. * @param file excel文件
  5. * @return 0表示失败,1表示成功
  6. * @throws Exception
  7. */
  8. String ajaxUploadExcel(MultipartFile file) throws Exception;
  9. /**
  10. * 导入excel
  11. * @return
  12. * @throws Exception
  13. */
  14. XSSFWorkbook exportExcelInfo() throws Exception;
  15. }

 service实现类

  1. @Service
  2. public class ExcelServiceImpl implements ExcelService {
  3. @Autowired
  4. private UserDao dao;
  5. @Autowired
  6. private UserService service;
  7. protected static Logger logger = LoggerFactory.getLogger(ExcelServiceImpl.class);
  8. public String ajaxUploadExcel(MultipartFile file) throws Exception {
  9. if(file.isEmpty()){
  10. try {
  11. throw new Exception("文件不存在!");
  12. } catch (Exception e) {
  13. logger.debug(e.getMessage());
  14. }
  15. }
  16. InputStream in =null;
  17. try {
  18. in = file.getInputStream();
  19. } catch (IOException e) {
  20. logger.debug(e.getMessage());
  21. }
  22. List<List<Object>> listob = null;
  23. try {
  24. //将文件中的数据转换成一个list集合
  25. listob = new ExcelUtil().getBankListByExcel(in,file.getOriginalFilename());
  26. } catch (Exception e) {
  27. logger.debug(e.getMessage());
  28. }
  29. //该处可调用service相应方法进行数据保存到数据库中,现只对数据输出
  30. for (int i = 0; i < listob.size(); i++) {
  31. User userExcel = new User();
  32. /*
  33. 设置值之前可以进行验证哪些字段是不能再添加的
  34. */
  35. if (StringUtils.isEmpty(String.valueOf(listob.get(i).get(1))) || StringUtils.isEmpty(String.valueOf(listob.get(i).get(0))) || StringUtils.isEmpty(String.valueOf(listob.get(i).get(3)))){
  36. throw new Exception("基本信息不能为空");
  37. }
  38. if (service.validateUseridcard(String.valueOf(listob.get(i).get(1)))){
  39. throw new Exception("身份证号码不能一致");
  40. }
  41. userExcel.setName(String.valueOf(listob.get(i).get(0))); // 表格的第一列 注意数据格式需要对应实体类属性
  42. userExcel.setIdcard(String.valueOf(listob.get(i).get(1))); // 表格的第二列
  43. userExcel.setMobiile(java.lang.String.valueOf(listob.get(i).get(2))); // 表格的第三列
  44. userExcel.setAddress(String.valueOf(listob.get(i).get(3))); // 表格的第四列
  45. userExcel.setAge(String.valueOf(listob.get(i).get(4))); // 表格的第五列
  46. //由于数据库中此字段是datetime,所以要将字符串时间格式:yyyy-MM-dd HH:mm,转为Date类型
  47. if (!StringUtils.isEmpty(listob.get(i).get(5))) {
  48. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
  49. userExcel.setBirtday(sdf.parse(String.valueOf(listob.get(i).get(5)))); // 表格的第六列
  50. }else {
  51. userExcel.setBirtday(new Date());
  52. }
  53. logger.info("读取的对象是:"+userExcel);
  54. //进行数据保存
  55. dao.saveUser(userExcel);
  56. }
  57. logger.info("文件导入成功!");
  58. return "1";
  59. }
  60. public XSSFWorkbook exportExcelInfo() throws Exception {
  61. List<Map<String,Object>> list = dao.getUsermap();
  62. List<ExcelBean> excel = new ArrayList<ExcelBean>();
  63. Map<Integer,List<ExcelBean>> map = new LinkedHashMap<Integer, List<ExcelBean>>();
  64. /*
  65. 设置标题栏(根据数据库的列名进行设置)
  66. 如果发现某一列没有内容可以自行debug(ExcelUtil.createTableRows)这个方法循环添加值那里的if是否进去然后设置为空了
  67. 多半是map的key没有写对
  68. */
  69. excel.add(new ExcelBean("主键","userid",0));
  70. excel.add(new ExcelBean("用户名","NAME",0));
  71. excel.add(new ExcelBean("身份证号码","idcard", 0));
  72. excel.add(new ExcelBean("手机号码","mobiile",0));
  73. excel.add(new ExcelBean("地址","address",0));
  74. excel.add(new ExcelBean("出生日期","birtday",0));
  75. excel.add(new ExcelBean("年龄","age",0));
  76. map.put(0,excel);
  77. String sheetName = "用户信息表";
  78. //调用ExcelUtil方法
  79. XSSFWorkbook xssfWorkbook = ExcelUtil.createExcelFile(User.class, list, map, sheetName);
  80. logger.info("文件导出成功");
  81. return xssfWorkbook;
  82. }
  83. }

 实体类

  1. public class ExcelBean implements Serializable {
  2. private String headTextName; //列头(标题)名
  3. private String propertyName; //对应字段名
  4. private Integer cols; //合并单元格数
  5. private XSSFCellStyle cellStyle;
  6. public ExcelBean(String headTextName, String propertyName, Integer cols, XSSFCellStyle cellStyle) {
  7. this.headTextName = headTextName;
  8. this.propertyName = propertyName;
  9. this.cols = cols;
  10. this.cellStyle = cellStyle;
  11. }
  12. public ExcelBean(String headTextName, String propertyName, Integer cols) {
  13. this.headTextName = headTextName;
  14. this.propertyName = propertyName;
  15. this.cols = cols;
  16. }
  17. public ExcelBean() {
  18. }
  19. public String getHeadTextName() {
  20. return headTextName;
  21. }
  22. public void setHeadTextName(String headTextName) {
  23. this.headTextName = headTextName;
  24. }
  25. public String getPropertyName() {
  26. return propertyName;
  27. }
  28. public void setPropertyName(String propertyName) {
  29. this.propertyName = propertyName;
  30. }
  31. public Integer getCols() {
  32. return cols;
  33. }
  34. public void setCols(Integer cols) {
  35. this.cols = cols;
  36. }
  37. public XSSFCellStyle getCellStyle() {
  38. return cellStyle;
  39. }
  40. public void setCellStyle(XSSFCellStyle cellStyle) {
  41. this.cellStyle = cellStyle;
  42. }
  43. }

  1. @RequestMapping(value="ajaxUpload", produces = "application/text; charset=utf-8",method = RequestMethod.POST)
  2. @ResponseBody
  3. public String UploadExcel(@RequestParam(value = "upfile",required = false) MultipartFile file){
  4. String msg = null;
  5. try {
  6. msg = excelService.ajaxUploadExcel(file);
  7. return msg;
  8. } catch (Exception e) {
  9. System.err.println(e.getMessage());
  10. logger.debug(e.getMessage());
  11. }
  12. return "0";
  13. }
  14. @RequestMapping(value = "downloadExcel",method = RequestMethod.POST)
  15. public void downloadExcel(HttpServletRequest request,HttpServletResponse response){
  16. //导出Excel对象
  17. XSSFWorkbook workbook = null;
  18. OutputStream output = null;
  19. BufferedOutputStream bufferedOutput = null;
  20. try {
  21. response.reset(); //清除buffer缓存
  22. //Map<String,Object> map=new HashMap<String,Object>();
  23. // 指定下载的文件名
  24. response.setContentType("application/vnd.ms-excel;charset=UTF-8");
  25. response.setHeader("Content-Disposition","attachment;filename="+new String("用户表.xlsx".getBytes(),"iso-8859-1"));
  26. //将查到的数据用XSSFWorkbook保存并创建一个流
  27. workbook = excelService.exportExcelInfo();
  28. output = response.getOutputStream();
  29. bufferedOutput = new BufferedOutputStream(output);
  30. bufferedOutput.flush();
  31. //最后通过流写进去
  32. workbook.write(bufferedOutput);
  33. } catch (Exception e) {
  34. System.err.println(e.getMessage());
  35. logger.debug(e.getMessage());
  36. }finally {
  37. try {
  38. bufferedOutput.close();
  39. } catch (IOException e) {
  40. e.printStackTrace();
  41. }
  42. }
  43. }

html

  1. <div class="form-group">
  2. <label for="upfile">上传表格(仅支持Excel)</label>
  3. <input id="upfile" type="file" class="file" accept=".xls,.xlsx" name="upfile"/>
  4. </div>
  5. <div class="form-group">
  6. <input type="button" class="form-control btn btn-success btn-sm" value="导入" id="importExcel">
  7. </div>
  8. <div class="form-group">
  9. <input class="form-control btn btn-success btn-sm" type="button" value="导出" id="downloadExcel">
  10. </div>

jquery

  1. $("#importExcel").on("click",function (){
  2. var formData = new FormData()
  3. //检验导入的文件是否为Excel文件
  4. var uploadFile = $('#upfile').val()
  5. formData.append("upfile",$("#upfile")[0].files[0])
  6. formData.append("name",uploadFile)
  7. if(uploadFile == null || uploadFile == ''){
  8. alert("请选择要上传的Excel文件")
  9. return false;
  10. }else{
  11. var fileExtend = uploadFile.substring(uploadFile.lastIndexOf('.')).toLowerCase();
  12. if(fileExtend == '.xls' || fileExtend == '.xlsx'){
  13. $.ajax({
  14. url:"ajaxUpload",
  15. type:"POST",
  16. data:formData,
  17. processData:false,
  18. contentType:false,
  19. success:function (data) {
  20. if (data == '1'){
  21. alert("导入成功")
  22. }else{
  23. alert("导入失败,日志有错误信息")
  24. }
  25. }
  26. })
  27. return true
  28. }else{
  29. alert("文件格式需为.xls格式或者.xlsx格式");
  30. return false
  31. }
  32. }
  33. })
  34. $("#downloadExcel").on("click",function (){
  35. //弹出对话框
  36. var result = confirm("是否导出Excel?")
  37. if (result) {
  38. $.post('downloadExcel')//直接发出请求不需要参数啥的
  39. }
  40. })
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/一键难忘520/article/detail/842546
推荐阅读
相关标签
  

闽ICP备14008679号