Spring集成POI实现Excel导入导出

痛定思痛。 2022-05-22 00:04 386阅读 0赞

Apache POI 是创建和维护操作各种符合Office Open XML(OOXML)标准和微软的OLE 2复合文档格式(OLE2)的Java API。用它可以使用Java读取和创建,修改MS Excel文件.而且,还可以使用Java读取和创建MS Word和MSPowerPoint文件。Apache POI 提供Java操作Excel解决方案(适用于Excel97-2008)。

  1. 简单理解就是通过POIjava可以与office建立联系。
  2. 本次项目实践基于SSM框架,简单封装了Excel批量导入导出功能,实现过程如下
  3. 1. maven导入java包:

[html] view plain copy

  1. org.apache.poi
  2. poi-ooxml
  3. 3.5-FINAL
  1. 2. 建立Excel实体--ExcelBean

[java] view plain copy

  1. /**
  2. *
  3. * @Description: 导入导出excel
  4. * @author haipeng
  5. * @date 2017年4月11日
  6. */
  7. public class ExcelBean implements java.io.Serializable {
  8. private String headTextName;//列头(标题)名
  9. private String propertyName;//对应字段名
  10. private Integer cols;//合并单元格数
  11. private XSSFCellStyle cellStyle;
  12. public ExcelBean(){
  13. }
  14. public ExcelBean(String headTextName, String propertyName){
  15. this.headTextName = headTextName;
  16. this.propertyName = propertyName;
  17. }
  18. public ExcelBean(String headTextName, String propertyName, Integer cols) {
  19. super();
  20. this.headTextName = headTextName;
  21. this.propertyName = propertyName;
  22. this.cols = cols;
  23. }
  24. public String getHeadTextName() {
  25. return headTextName;
  26. }
  27. public void setHeadTextName(String headTextName) {
  28. this.headTextName = headTextName;
  29. }
  30. public String getPropertyName() {
  31. return propertyName;
  32. }
  33. public void setPropertyName(String propertyName) {
  34. this.propertyName = propertyName;
  35. }
  36. public Integer getCols() {
  37. return cols;
  38. }
  39. public void setCols(Integer cols) {
  40. this.cols = cols;
  41. }
  42. public XSSFCellStyle getCellStyle() {
  43. return cellStyle;
  44. }
  45. public void setCellStyle(XSSFCellStyle cellStyle) {
  46. this.cellStyle = cellStyle;
  47. }
  48. }

    1. 封装Excel工具类—ExcelUtils

[java] view plain copy

  1. public class ExcelUtils {
  2. private final static String excel2003L =”.xls”; //2003- 版本的excel
  3. private final static String excel2007U =”.xlsx”; //2007+ 版本的excel
  4. /*************************************文件上传****************************/
  5. public static List> getBankListByExcel(InputStream in,String fileName) throws Exception{
  6. List> list = null;
  7. //创建Excel工作薄
  8. Workbook work = getWorkbook(in,fileName);
  9. if(null == work){
  10. throw new Exception(“创建Excel工作薄为空!”);
  11. }
  12. Sheet sheet = null;
  13. Row row = null;
  14. Cell cell = null;
  15. list = new ArrayList>();
  16. //遍历Excel中所有的sheet
  17. for (int i = 0; i < work.getNumberOfSheets(); i++) {
  18. sheet = work.getSheetAt(i);
  19. if(sheet==null){ continue;}
  20. //遍历当前sheet中的所有行
  21. for (int j = sheet.getFirstRowNum(); j < sheet.getLastRowNum(); j++) {
  22. row = sheet.getRow(j);
  23. if(row==null||row.getFirstCellNum()==j){ continue;}
  24. //遍历所有的列
  25. List li = new ArrayList();
  26. for (int y = row.getFirstCellNum(); y < row.getLastCellNum(); y++) {
  27. cell = row.getCell(y);
  28. li.add(getCellValue(cell));
  29. }
  30. list.add(li);
  31. }
  32. }
  33. // work.close();
  34. return list;
  35. }
  36. /**
  37. * 描述:根据文件后缀,自适应上传文件的版本
  38. * @param inStr,fileName
  39. * @return
  40. * @throws Exception
  41. */
  42. public static Workbook getWorkbook(InputStream inStr,String fileName) throws Exception{
  43. Workbook wb = null;
  44. String fileType = fileName.substring(fileName.lastIndexOf(“.”));
  45. if(excel2003L.equals(fileType)){
  46. wb = new HSSFWorkbook(inStr); //2003-
  47. }else if(excel2007U.equals(fileType)){
  48. wb = new XSSFWorkbook(inStr); //2007+
  49. }else{
  50. throw new Exception(“解析的文件格式有误!”);
  51. }
  52. return wb;
  53. }
  54. /**
  55. * 描述:对表格中数值进行格式化
  56. * @param cell
  57. * @return
  58. */
  59. public static Object getCellValue(Cell cell){
  60. Object value = null;
  61. DecimalFormat df = new DecimalFormat(“0”); //格式化number String字符
  62. SimpleDateFormat sdf = new SimpleDateFormat(“yyy-MM-dd”); //日期格式化
  63. DecimalFormat df2 = new DecimalFormat(“0.00”); //格式化数字
  64. switch (cell.getCellType()) {
  65. case Cell.CELL_TYPE_STRING:
  66. value = cell.getRichStringCellValue().getString();
  67. break;
  68. case Cell.CELL_TYPE_NUMERIC:
  69. if(“General”.equals(cell.getCellStyle().getDataFormatString())){
  70. value = df.format(cell.getNumericCellValue());
  71. }else if(“m/d/yy”.equals(cell.getCellStyle().getDataFormatString())){
  72. value = sdf.format(cell.getDateCellValue());
  73. }else{
  74. value = df2.format(cell.getNumericCellValue());
  75. }
  76. break;
  77. case Cell.CELL_TYPE_BOOLEAN:
  78. value = cell.getBooleanCellValue();
  79. break;
  80. case Cell.CELL_TYPE_BLANK:
  81. value = “”;
  82. break;
  83. default:
  84. break;
  85. }
  86. return value;
  87. }
  88. /****************************************上传结束***************************************
  89. /**
  90. * 多列头创建EXCEL
  91. *
  92. * @param sheetName 工作簿名称
  93. * @param clazz 数据源model类型
  94. * @param objs excel标题列以及对应model字段名
  95. * @param map 标题列行数以及cell字体样式
  96. * @return
  97. * @throws IllegalArgumentException
  98. * @throws IllegalAccessException
  99. * @throws InvocationTargetException
  100. * @throws ClassNotFoundException
  101. * @throws IntrospectionException
  102. * @throws ParseException
  103. */
  104. public static XSSFWorkbook createExcelFile(Class clazz, List objs,Map> map,String sheetName) throws IllegalArgumentException,IllegalAccessException,
  105. InvocationTargetException, ClassNotFoundException, IntrospectionException, ParseException{
  106. // 创建新的Excel 工作簿
  107. XSSFWorkbook workbook = new XSSFWorkbook();
  108. // 在Excel工作簿中建一工作表,其名为缺省值, 也可以指定Sheet名称
  109. XSSFSheet sheet = workbook.createSheet(sheetName);
  110. // 以下为excel的字体样式以及excel的标题与内容的创建,下面会具体分析;
  111. createFont(workbook);//字体样式
  112. createTableHeader(sheet, map);//创建标题(头)
  113. createTableRows(sheet, map, objs, clazz);//创建内容
  114. return workbook;
  115. }
  116. private static XSSFCellStyle fontStyle;
  117. private static XSSFCellStyle fontStyle2;
  118. public static void createFont(XSSFWorkbook workbook) {
  119. // 表头
  120. fontStyle = workbook.createCellStyle();
  121. XSSFFont font1 = workbook.createFont();
  122. font1.setBoldweight(XSSFFont.BOLDWEIGHT_BOLD);
  123. font1.setFontName(“黑体”);
  124. font1.setFontHeightInPoints((short) 14);// 设置字体大小
  125. fontStyle.setFont(font1);
  126. fontStyle.setBorderBottom(XSSFCellStyle.BORDER_THIN); // 下边框
  127. fontStyle.setBorderLeft(XSSFCellStyle.BORDER_THIN);// 左边框
  128. fontStyle.setBorderTop(XSSFCellStyle.BORDER_THIN);// 上边框
  129. fontStyle.setBorderRight(XSSFCellStyle.BORDER_THIN);// 右边框
  130. fontStyle.setAlignment(XSSFCellStyle.ALIGN_CENTER); // 居中
  131. // 内容
  132. fontStyle2=workbook.createCellStyle();
  133. XSSFFont font2 = workbook.createFont();
  134. font2.setFontName(“宋体”);
  135. font2.setFontHeightInPoints((short) 10);// 设置字体大小
  136. fontStyle2.setFont(font2);
  137. fontStyle2.setBorderBottom(XSSFCellStyle.BORDER_THIN); // 下边框
  138. fontStyle2.setBorderLeft(XSSFCellStyle.BORDER_THIN);// 左边框
  139. fontStyle2.setBorderTop(XSSFCellStyle.BORDER_THIN);// 上边框
  140. fontStyle2.setBorderRight(XSSFCellStyle.BORDER_THIN);// 右边框
  141. fontStyle2.setAlignment(XSSFCellStyle.ALIGN_CENTER); // 居中
  142. }
  143. /**
  144. * 根据ExcelMapping 生成列头(多行列头)
  145. *
  146. * @param sheet
  147. * 工作簿
  148. * @param map
  149. * 每行每个单元格对应的列头信息
  150. */
  151. public static final void createTableHeader(XSSFSheet sheet, Map> map) {
  152. int startIndex=0;//cell起始位置
  153. int endIndex=0;//cell终止位置
  154. for (Map.Entry> entry : map.entrySet()) {
  155. XSSFRow row = sheet.createRow(entry.getKey());
  156. List excels = entry.getValue();
  157. for (int x = 0; x < excels.size(); x++) {
  158. //合并单元格
  159. if(excels.get(x).getCols()>1){
  160. if(x==0){
  161. endIndex+=excels.get(x).getCols()-1;
  162. CellRangeAddress range=new CellRangeAddress(0,0,startIndex,endIndex);
  163. sheet.addMergedRegion(range);
  164. startIndex+=excels.get(x).getCols();
  165. }else{
  166. endIndex+=excels.get(x).getCols();
  167. CellRangeAddress range=new CellRangeAddress(0,0,startIndex,endIndex);
  168. sheet.addMergedRegion(range);
  169. startIndex+=excels.get(x).getCols();
  170. }
  171. XSSFCell cell = row.createCell(startIndex-excels.get(x).getCols());
  172. cell.setCellValue(excels.get(x).getHeadTextName());// 设置内容
  173. if (excels.get(x).getCellStyle() != null) {
  174. cell.setCellStyle(excels.get(x).getCellStyle());// 设置格式
  175. }
  176. cell.setCellStyle(fontStyle);
  177. }else{
  178. XSSFCell cell = row.createCell(x);
  179. cell.setCellValue(excels.get(x).getHeadTextName());// 设置内容
  180. if (excels.get(x).getCellStyle() != null) {
  181. cell.setCellStyle(excels.get(x).getCellStyle());// 设置格式
  182. }
  183. cell.setCellStyle(fontStyle);
  184. }
  185. }
  186. }
  187. }
  188. /**
  189. *
  190. * @param sheet
  191. * @param map
  192. * @param objs
  193. * @param clazz
  194. */
  195. @SuppressWarnings(“rawtypes”)
  196. public static void createTableRows(XSSFSheet sheet, Map> map, List objs, Class clazz)
  197. throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, IntrospectionException,
  198. ClassNotFoundException, ParseException {
  199. int rowindex = map.size();
  200. int maxKey = 0;
  201. List ems = new ArrayList<>();
  202. for (Map.Entry> entry : map.entrySet()) {
  203. if (entry.getKey() > maxKey) {
  204. maxKey = entry.getKey();
  205. }
  206. }
  207. ems = map.get(maxKey);
  208. List widths = new ArrayList(ems.size());
  209. for (Object obj : objs) {
  210. XSSFRow row = sheet.createRow(rowindex);
  211. for (int i = 0; i < ems.size(); i++) {
  212. ExcelBean em = (ExcelBean) ems.get(i);
  213. // 获得get方法
  214. PropertyDescriptor pd = new PropertyDescriptor(em.getPropertyName(), clazz);
  215. Method getMethod = pd.getReadMethod();
  216. Object rtn = getMethod.invoke(obj);
  217. String value = “”;
  218. // 如果是日期类型 进行 转换
  219. if (rtn != null) {
  220. if (rtn instanceof Date) {
  221. value = DateUtils.date2String((Date) rtn,”yyyy-MM-dd”);
  222. } else if(rtn instanceof BigDecimal){
  223. NumberFormat nf = new DecimalFormat(“#,##0.00”);
  224. value=nf.format((BigDecimal)rtn).toString();
  225. } else if((rtn instanceof Integer) && (Integer.valueOf(rtn.toString())<0 )){
  226. value=”—“;
  227. }else {
  228. value = rtn.toString();
  229. }
  230. }
  231. XSSFCell cell = row.createCell(i);
  232. cell.setCellValue(value);
  233. cell.setCellType(XSSFCell.CELL_TYPE_STRING);
  234. cell.setCellStyle(fontStyle2);
  235. // 获得最大列宽
  236. int width = value.getBytes().length * 300;
  237. // 还未设置,设置当前
  238. if (widths.size() <= i) {
  239. widths.add(width);
  240. continue;
  241. }
  242. // 比原来大,更新数据
  243. if (width > widths.get(i)) {
  244. widths.set(i, width);
  245. }
  246. }
  247. rowindex++;
  248. }
  249. // 设置列宽
  250. for (int index = 0; index < widths.size(); index++) {
  251. Integer width = widths.get(index);
  252. width = width < 2500 ? 2500 : width + 300;
  253. width = width > 10000 ? 10000 + 300 : width + 300;
  254. sheet.setColumnWidth(index, width);
  255. }
  256. }
  257. }
    1. 4. HTML页面导入需要的js

    [html] view plain copy

    1. 5. HTML添加测试控件

    [java] view plain copy

    1. 导出
    1. 6. 导出通过a标签的get请求即可以实现,导入则通过ajaxpost请求实现:

    [java] view plain copy

    1. $(‘#upLoadPayerCreditInfoExcel’).click(function(){
    2. var cacheVersion=$(“#cacheVersion”).val();
    3. if(checkData()){
    4. $(‘#uploadForm’).ajaxSubmit({
    5. url:$(“#root”).val()+’/creditInfo/uploadReceiverCreditInfoExcel.html’,
    6. data:{ ‘cacheVersion’:cacheVersion},
    7. dataType: ‘text’
    8. });
    9. }
    10. });
    11. //JS校验form表单信息
    12. function checkData(){
    13. var fileDir = $(“#upfile”).val();
    14. var suffix = fileDir.substr(fileDir.lastIndexOf(“.”));
    15. if(“” == fileDir){
    16. alert(“选择需要导入的Excel文件!”);
    17. return false;
    18. }
    19. if(“.xls” != suffix && “.xlsx” != suffix ){
    20. alert(“选择Excel格式的文件导入!”);
    21. return false;
    22. }
    23. return true;
    24. }
    1. 7. controller端实现
    2. 导出:

    [java] view plain copy

    1. @RequestMapping(value = “/downLoadPayerCreditInfoExcel”, method = RequestMethod.GET)
    2. @ResponseBody
    3. public void downLoadPayerCreditInfoExcel(HttpServletRequest request,HttpServletResponse response,HttpSession session){
    4. response.reset();
    5. SimpleDateFormat sdf = new SimpleDateFormat(“yyyyMMddhhmmssms”);
    6. String dateStr = sdf.format(new Date());
    7. Long companyId=UserUtils.getCompanyIdBySession(session);
    8. Map map=new HashMap();
    9. // 指定下载的文件名
    10. response.setHeader(“Content-Disposition”, “attachment;filename=” +dateStr+”.xlsx”);
    11. response.setContentType(“application/vnd.ms-excel;charset=UTF-8”);
    12. response.setHeader(“Pragma”, “no-cache”);
    13. response.setHeader(“Cache-Control”, “no-cache”);
    14. response.setDateHeader(“Expires”, 0);
    15. XSSFWorkbook workbook=null;
    16. try {
    17. //导出Excel对象
    18. workbook = creditInfoService.exportPayerCreditInfoExcel(companyId);
    19. } catch (IllegalArgumentException | IllegalAccessException
    20. | InvocationTargetException | ClassNotFoundException
    21. | IntrospectionException | ParseException e1) {
    22. e1.printStackTrace();
    23. }
    24. OutputStream output;
    25. try {
    26. output = response.getOutputStream();
    27. BufferedOutputStream bufferedOutPut = new BufferedOutputStream(output);
    28. bufferedOutPut.flush();
    29. workbook.write(bufferedOutPut);
    30. bufferedOutPut.close();
    31. } catch (IOException e) {
    32. e.printStackTrace();
    33. }
    34. }
    1. 导入:

    [java] view plain copy

    1. @ResponseBody
    2. @RequestMapping(value=”uploadPayerCreditInfoExcel”,method={RequestMethod.GET,RequestMethod.POST})
    3. Public void uploadPayerCreditInfoExcel(HttpServletRequest request,HttpServletResponse response,HttpSession session) throws Exception {
    4. MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
    5. MultipartFile file = multipartRequest.getFile(“upfile”);
    6. if(file.isEmpty()){
    7. throw new Exception(“文件不存在!”);
    8. }
    9. Long companyId=UserUtils.getCompanyIdBySession(session);
    10. Long userId=UserUtils.getUserIdBySession(session);
    11. InputStream in = file.getInputStream();
    12. creditInfoService.uploadPayerCreditInfoExcel(in,file,companyId,userId);
    13. in.close();
    14. PrintWriter out = null;
    15. response.setCharacterEncoding(“utf-8”); //防止ajax接受到的中文信息乱码
    16. out = response.getWriter();
    17. out.print(“文件导入成功!”);
    18. out.flush();
    19. out.close();
    20. }
    1. 8service
    2. 导入,从excel中获得数据放入List<List<object>>中,然后遍历放入实体,执行插入操作:

    [java] view plain copy

    1. public void uploadPayerCreditInfoExcel(InputStream in, MultipartFile file,Long companyId,Long userId) throws Exception {
    2. List> listob = ExcelUtils.getBankListByExcel(in,file.getOriginalFilename());
    3. List creditInfoList=new ArrayList();
    4. for (int i = 0; i < listob.size(); i++) {
    5. List ob = listob.get(i);
    6. CreditInfoBean creditInfoBean = new CreditInfoBean();
    7. creditInfoBean.setCompanyName(String.valueOf(ob.get(0)));
    8. creditInfoBean.setBillType(String.valueOf(ob.get(1)));
    9. creditInfoBean.setBillNumber(String.valueOf(ob.get(2)));
    10. BigDecimal bd=new BigDecimal(String.valueOf(ob.get(3)));
    11. creditInfoBean.setBuyerBillAmount(bd.setScale(2, BigDecimal.ROUND_HALF_UP));
    12. creditInfoBean.setReceiveTime(String.valueOf(ob.get(4)));
    13. creditInfoBean.setBuyerRemark(String.valueOf(ob.get(5)));
    14. creditInfoList.add(creditInfoBean);
    15. }
    16. }
      1. 导出:

      [java] view plain copy

      1. public XSSFWorkbook exportPayerCreditInfoExcel(Long companyId) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException, ClassNotFoundException, IntrospectionException, com.sun.tools.example.debug.expr.ParseException {
      2. List creditInfoList=creditInfoDao.listAllPayerCreditInfoPage(companyId);
      3. List ems=new ArrayList<>();
      4. Map>map=new LinkedHashMap<>();
      5. XSSFWorkbook book=null;
      6. ems.add(new ExcelBean(“供应商名称”,”companyName”,0));
      7. ems.add(new ExcelBean(“票据类型”,”billType”,0));
      8. ems.add(new ExcelBean(“票据号”,”billNumber”,0));
      9. ems.add(new ExcelBean(“买方是否参与”,”isBuyerIquidation”,0));
      10. ems.add(new ExcelBean(“票据金额”,”buyerBillAmount”,0));
      11. ems.add(new ExcelBean(“应付日期”,”buyerPayTime”,0));
      12. ems.add(new ExcelBean(“剩余天数”,”overplusDays”,0));
      13. ems.add(new ExcelBean(“状态”,”buyerBillStatus”,0));
      14. map.put(0, ems);
      15. List afterChangeList=changeBuyerStatus(creditInfoList);
      16. book=ExcelUtils.createExcelFile(CreditInfoBean.class, afterChangeList, map, “应付账款信息”);
      17. return book;
      18. }

发表评论

表情:
评论列表 (有 0 条评论,386人围观)

还没有评论,来说两句吧...

相关阅读