Java implementation file batch import and export practice (compatible with xls, xlsx)

1 Introduction

Java implements file import and export database. It is a relatively common function in most systems at present. Today, I write a small demo to understand the principle. Students who have never contacted can also take a look and refer to it.

At present, the import and export technologies I have come into contact with mainly include POI and iReport. Poi is mainly used to import some data into the database in batches, and iReport is used for report export. There is also a way similar to poi in jxl, but it seems that it hasn't been updated for a long time. Offices after 2007 don't seem to support it, so I won't talk about it here.

2. Detailed explanation of POI usage

2.1 What is Apache POI?

Apache POI is an open source library of the Apache Software Foundation. POI provides APIs for Java programs to read and write Microsoft Office format files.

2.2 POI jar package import

This tutorial uses the maven project, and the jar package version uses poi-3.14 and poi-ooxml-3.14. The latest version is 3.16. Because the related api has been updated after 3.15, some operations may be different, please pay attention to it.

<!-- poi的包 3.15版本后单元格类型获取方式有调整 -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.14</version>
        </dependency>
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>3.14</version>
        </dependency>

2.3 POI API explanation

2.3.1 Structure

HSSF-Provides the function of reading and writing files in Microsoft Excel format.
XSSF-provides the function of reading and writing Microsoft Excel OOXML format files.
HWPF-Provides the function of reading and writing Microsoft Word format files.
HSLF-Provides the function of reading and writing Microsoft PowerPoint format files.
HDGF-Provides the function of reading and writing Microsoft Visio format files.

2.3.2 Object

This article mainly introduces the two components of HSSF and XSSF. Simply speaking, HSSF is used to operate the excel.xls file before the Office 2007 version, and XSSF is used to operate the excel.xlsx file after the Office 2007 version. Note that the suffixes of the two are different.

HSSF is in the org.apache.poi.hssf.usermodel package. It implements the Workbook interface for the .xls format in Excel files

Common components:


HSSFWorkbook: excel document object HSSFSheet: excel form
HSSFRow: excel row
HSSFCell: excel grid cell
HSSFFont: excel font
HSSFDataFormat: date format
HSSFHeader: sheet header
HSSFFooter: sheet tail (the effect can only be seen when printed)

style:

HSSFCellStyle: cell style

Auxiliary operations include:

HSSFDateUtil: Date
HSSFPrintSetup: Print
HSSFErrorConstants: Error message table

XSSF is in the org.apache.xssf.usemodel package and implements the Workbook interface for the .xlsx format in the Excel file

Common components:

XSSFWorkbook: excel document object
XSSFSheet: excel form
XSSFRow: excel row
XSSFCell: excel grid cell
XSSFFont: excel font
XSSFDataFormat: date format

Similar to HSSF;

2.3.3 Description of field types common to two components

In fact, the two components are for the two formats of excel, and most of the operations are the same.


单元格类型                        描述CELL_TYPE_BLANK          代表空白单元格CELL_TYPE_BOOLEAN        代表布尔单元(true或false)CELL_TYPE_ERROR          表示在单元的误差值CELL_TYPE_FORMULA        表示一个单元格公式的结果CELL_TYPE_NUMERIC        表示对一个单元的数字数据CELL_TYPE_STRING         表示对一个单元串(文本)

2.3.4 Operation steps

Taking HSSF as an example, XSSF operations are the same.

First, understand the organization of an Excel file. An Excel file corresponds to a workbook (HSSFWorkbook). A workbook can be composed of multiple sheets (HSSFSheet). A sheet is composed of multiple rows (HSSFRow). It is composed of multiple cells (HSSFCell).

1. Use HSSFWorkbook to open or create "Excel file object"

2. Use HSSFWorkbook object to return or create Sheet object

3. Use the Sheet object to return the row object, and use the row object to get the Cell object

4. Read and write to the Cell object.

3. Code operation

3.1 Effect picture

Convention, look at the renderings before posting the code

One for each of the two formats of Excel files:


 


After importing: (I imported twice and did not check)

Export effect:

3.2 Detailed code

Here I take Spring+SpringMVC+Mybatis as the basis, and extend: SpringBoot+Mybatis multi-module project construction tutorial

Controller:

package com.root.controller;

import java.util.List;

import javax.servlet.http.HttpServletResponse;

import org.apache.poi.ss.formula.functions.Mode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import com.root.pojo.Student;
import com.root.service.StudentService;
/**
 * 
 * @author SpringRoot
 *
 */
@Controller
public class StudentController {
    @Autowired
    private StudentService studentService;
    /**
     * 批量导入表单数据
     * 
     * @param request
     * @param myfile
     * @return
     */

    @RequestMapping(value="/importExcel",method=RequestMethod.POST)
    public String importExcel(@RequestParam("myfile") MultipartFile myFile) {
        ModelAndView modelAndView = new ModelAndView();
        try {
            Integer num = studentService.importExcel(myFile);
        } catch (Exception e) {
            modelAndView.addObject("msg", e.getMessage());
            return "index";
        }
        modelAndView.addObject("msg", "数据导入成功");

        return "index";
    }

    @RequestMapping(value="/exportExcel",method=RequestMethod.GET)
    public void exportExcel(HttpServletResponse response) {    
        try {
            studentService.exportExcel(response);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }



}

Service

package com.root.service.impl;

import java.io.OutputStream;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import com.root.mapper.StudentMapper;
import com.root.pojo.Student;
import com.root.service.StudentService;
/**
 * 
 * @author SpringRoot
 *
 */
@Service
public class StudentServiceImpl implements StudentService{
    private final static String XLS = "xls";  
    private final static String XLSX = "xlsx"; 
    @Autowired
    private StudentMapper studentMapper;
    /**
     * 导入Excel,兼容xls和xlsx
     */
    @SuppressWarnings("resource")
    public Integer importExcel(MultipartFile myFile) throws Exception {
        //        1、用HSSFWorkbook打开或者创建“Excel文件对象”
        //
        //        2、用HSSFWorkbook对象返回或者创建Sheet对象
        //
        //        3、用Sheet对象返回行对象,用行对象得到Cell对象
        //
        //        4、对Cell对象读写。
        //获得文件名  
        Workbook workbook = null ;
        String fileName = myFile.getOriginalFilename(); 
        if(fileName.endsWith(XLS)){  
            //2003  
            workbook = new HSSFWorkbook(myFile.getInputStream());  
        }else if(fileName.endsWith(XLSX)){  
            //2007  
            workbook = new XSSFWorkbook(myFile.getInputStream());  
        }else{
            throw new Exception("文件不是Excel文件");
        }

        Sheet sheet = workbook.getSheet("Sheet1");
        int rows = sheet.getLastRowNum();// 指的行数,一共有多少行+
        if(rows==0){
            throw new Exception("请填写数据");
        }
        for (int i = 1; i <= rows+1; i++) {
            // 读取左上端单元格
            Row row = sheet.getRow(i);
            // 行不为空
            if (row != null) {
                // **读取cell**
                Student student = new Student();
                //姓名
                String name = getCellValue(row.getCell(0));
                student.setName(name);
                //班级
                String classes = getCellValue(row.getCell(1));
                student.setClasses(classes);
                //分数
                String scoreString = getCellValue(row.getCell(2));
                if (!StringUtils.isEmpty(scoreString)) {
                    Integer score = Integer.parseInt(scoreString);
                    student.setScore(score);
                }
                //考试时间
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");//小写的mm表示的是分钟  
                String dateString = getCellValue(row.getCell(3));  
                if (!StringUtils.isEmpty(dateString)) {
                    Date date=sdf.parse(dateString);  
                    student.setTime(date);
                }
                studentMapper.insert(student);
            }
        }
        return rows-1;
    }

    /**
     * 获得Cell内容
     * 
     * @param cell
     * @return
     */
    public String getCellValue(Cell cell) {
        String value = "";
        if (cell != null) {
            // 以下是判断数据的类型
            switch (cell.getCellType()) {
            case HSSFCell.CELL_TYPE_NUMERIC: // 数字
                value = cell.getNumericCellValue() + "";
                if (HSSFDateUtil.isCellDateFormatted(cell)) {
                    Date date = cell.getDateCellValue();
                    if (date != null) {
                        value = new SimpleDateFormat("yyyy-MM-dd").format(date);
                    } else {
                        value = "";
                    }
                } else {
                    value = new DecimalFormat("0").format(cell.getNumericCellValue());
                }
                break;
            case HSSFCell.CELL_TYPE_STRING: // 字符串
                value = cell.getStringCellValue();
                break;
            case HSSFCell.CELL_TYPE_BOOLEAN: // Boolean
                value = cell.getBooleanCellValue() + "";
                break;
            case HSSFCell.CELL_TYPE_FORMULA: // 公式
                value = cell.getCellFormula() + "";
                break;
            case HSSFCell.CELL_TYPE_BLANK: // 空值
                value = "";
                break;
            case HSSFCell.CELL_TYPE_ERROR: // 故障
                value = "非法字符";
                break;
            default:
                value = "未知类型";
                break;
            }
        }
        return value.trim();
    }
    /**
     * 导出excel文件
     */
    public void exportExcel(HttpServletResponse response) throws Exception {
        // 第一步,创建一个webbook,对应一个Excel文件  
        HSSFWorkbook wb = new HSSFWorkbook();  
        // 第二步,在webbook中添加一个sheet,对应Excel文件中的sheet  
        HSSFSheet sheet = wb.createSheet("Sheet1");  
        // 第三步,在sheet中添加表头第0行,注意老版本poi对Excel的行数列数有限制short  
        HSSFRow row = sheet.createRow(0);  
        // 第四步,创建单元格,并设置值表头 设置表头居中  
        HSSFCellStyle style = wb.createCellStyle();  
        style.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 创建一个居中格式  

        HSSFCell cell = row.createCell(0);
        cell.setCellValue("姓名");  
        cell.setCellStyle(style);  
        cell = row.createCell(1);  
        cell.setCellValue("班级");  
        cell.setCellStyle(style);  
        cell = row.createCell(2);  
        cell.setCellValue("分数");  
        cell.setCellStyle(style);  
        cell = row.createCell(3);  
        cell.setCellValue("时间");  
        cell.setCellStyle(style);  

        // 第五步,写入实体数据 实际应用中这些数据从数据库得到,  
        List<Student> list = studentMapper.selectAll();  

        for (int i = 0; i < list.size(); i++){  
            row = sheet.createRow(i + 1);  
            Student stu = list.get(i);  
            // 第四步,创建单元格,并设置值  
            row.createCell(0).setCellValue(stu.getName());  
            row.createCell(1).setCellValue(stu.getClasses());  
            row.createCell(2).setCellValue(stu.getScore());  
            cell = row.createCell(3);  
            cell.setCellValue(new SimpleDateFormat("yyyy-MM-dd").format(stu.getTime()));  
        }          
        //第六步,输出Excel文件
        OutputStream output=response.getOutputStream();
        response.reset();
        long filename = System.currentTimeMillis();
        SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");//设置日期格式
        String fileName = df.format(new Date());// new Date()为获取当前系统时间
        response.setHeader("Content-disposition", "attachment; filename="+fileName+".xls");
        response.setContentType("application/msexcel");        
        wb.write(output);
        output.close();
    }  

}

3.3 Export file api supplement

You can see that the service code above is only the most basic export.

In practical applications, the exported Excel files often need to be read and printed, which requires the layout and style settings of the output Excel documents. The main operations include merging cells, setting cell styles, and setting font styles.

3.3.1 Cell Merge

Use the addMergedRegion() method of HSSFSheet

public int addMergedRegion(CellRangeAddress region)

The parameter CellRangeAddress represents the area to be merged, and the construction method is as follows: the start row, the end row, the start column, and the end column in turn

CellRangeAddress(int firstRow, int lastRow, int firstCol, int lastCol)

3.3.2 Set the row height and column width of a cell

HSSFSheet sheet=wb.createSheet();
sheet.setDefaultRowHeightInPoints(10);//设置缺省列高sheet.setDefaultColumnWidth(20);//设置缺省列宽
//设置指定列的列宽,256 * 50这种写法是因为width参数单位是单个字符的256分之一
sheet.setColumnWidth(cell.getColumnIndex(), 256 * 50);

3.3.3 Set cell style

1. Create HSSFCellStyle

HSSFCellStyle cellStyle=wkb.createCellStyle()

2. Set the style

// 设置单元格的横向和纵向对齐方式,具体参数就不列了,参考HSSFCellStyle
  cellStyle.setAlignment(HSSFCellStyle.ALIGN_JUSTIFY);
  cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
  /* 设置单元格的填充方式,以及前景颜色和背景颜色
   三点注意:
   1.如果需要前景颜色或背景颜色,一定要指定填充方式,两者顺序无所谓;
   2.如果同时存在前景颜色和背景颜色,前景颜色的设置要写在前面;
   3.前景颜色不是字体颜色。
  */
  //设置填充方式(填充图案)
  cellStyle.setFillPattern(HSSFCellStyle.DIAMONDS);
  //设置前景色
  cellStyle.setFillForegroundColor(HSSFColor.RED.index);
  //设置背景颜色
  cellStyle.setFillBackgroundColor(HSSFColor.LIGHT_YELLOW.index);
  // 设置单元格底部的边框及其样式和颜色
  // 这里仅设置了底边边框,左边框、右边框和顶边框同理可设
  cellStyle.setBorderBottom(HSSFCellStyle.BORDER_SLANTED_DASH_DOT);
  cellStyle.setBottomBorderColor(HSSFColor.DARK_RED.index);
  //设置日期型数据的显示样式
  cellStyle.setDataFormat(HSSFDataFormat.getBuiltinFormat("m/d/yy h:mm"));

3. Apply styles to cells

  cell.setCellStyle(cellStyle);
  //将样式应用到行,但有些样式只对单元格起作用
  row.setRowStyle(cellStyle);

3.3.4 Set font style

1. Create the HSSFFont object (call the createFont method of HSSFWorkbook)

HSSFWorkbook wb=new HSSFWorkbook();
HSSFFont  fontStyle=wb.createFont();
HSSFWorkbook wb=new HSSFWorkbook ();

2. Set various styles of fonts

  //设置字体样式
  fontStyle.setFontName("宋体");  
  //设置字体高度
  fontStyle.setFontHeightInPoints((short)20);  
  //设置字体颜色
  font.setColor(HSSFColor.BLUE.index);
  //设置粗体
  fontStyle.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
  //设置斜体
  font.setItalic(true);
  //设置下划线
  font.setUnderline(HSSFFont.U_SINGLE);

3. Set the font to the cell style

//字体也是单元格格式的一部分,所以从属于HSSFCellStyle
// 将字体对象赋值给单元格样式对象
cellStyle.setFont(font);
// 将单元格样式应用于单元格
cell.setCellStyle(cellStyle);

You can see that exporting files with poi is quite troublesome. I will introduce the irport method next time.

The exported api is basically these. Finally, I hope the above can be helpful to everyone.

Guess you like

Origin blog.csdn.net/baidu_39322753/article/details/104944229