Tags: Tax Service System project


preface

Going back to our user module, we see that there are still two features left unfinished:

We didn’t learn anything about importing or exporting data from web pages into Excel files. However, excel is relatively common in Java, so there are components for us to use

There are two mainstream toolkits for using Excel in JAVA

  • JXL
  • POI

This time we mainly learn POI operation Excel.

JXL has a bug that only works with 03 or earlier versions of Excel, while POI can work with 97-07 versions.

POI basis

Object oriented look at Excel

First of all, if you want to use Java to manipulate Excel, you must specify excel related content with objects. Let’s see what Excel consists of:

POI looks at it this way:

  • The entire Excel is called a workbook
  • Many tables can be created under a workbook, called worksheets
  • The worksheet has very many rows
  • Rows can be subdivided into cells [specify row columns can be positioned anywhere in the worksheet]

After giving us a thorough analysis, we find that there is a subordinate relationship between them:

  • Worksheets are subordinate to workbooks
  • Rows are subordinate to the worksheet
  • Cells are subordinate to rows


Procedures for Operating Excel

Import the POI development package:

  • Poi – ooxml – 3.10.1-20140818. The jar.
  • Poi – ooxml – schemas – 3.10.1-20140818. The jar,
  • And copy xmlBeans-2.6.0.jar in ooxmL-lib, dom4J-1.6.1.jar (dom4j usually exists when the project is imported).
  • Poi – ooxml – 3.11-20141221. The jar

/** * There are only 4 steps to Excel using POI1: ** Create/read workbooks * Create/read worksheets * Create/read rows * Create/read cells ** ** /
Copy the code

Create Excel and write data


    @Test
    public void testWrite(a) throws IOException {

        // Create a workbook
        HSSFWorkbook workbook = new HSSFWorkbook();

        // Create a worksheet
        HSSFSheet sheet = workbook.createSheet("I'm the new worksheet.");

        // Create row, coordinates start at 0, I create row 3
        HSSFRow row = sheet.createRow(2);

        // Create a cell with coordinates starting at 0, so row 3 and column 3
        HSSFCell cell = row.createCell(2);

        // Write data to cells
        cell.setCellValue("helloWorld");

        // Write the workbook to hard disk
        FileOutputStream outputStream = new FileOutputStream("C:\\ workbook.xls");
        workbook.write(outputStream);

        / / close the flow
        workbook.close();
        outputStream.close();

    }
Copy the code


Read Excel data


    @Test
    public void testRead(a) throws IOException {

        // Get input stream, read Excel data
        FileInputStream inputStream = new FileInputStream("C:\\ workbook.xls");

        // Create a workbook
        HSSFWorkbook workbook = new HSSFWorkbook(inputStream);

        // Get the worksheet
        HSSFSheet sheet = workbook.getSheetAt(0);

        / / line
        HSSFRow row = sheet.getRow(2);

        // Get the cell
        HSSFCell cell = row.getCell(2);

        // Get the cell data
        String cellValue = cell.getStringCellValue();

        System.out.println(cellValue);

    }
Copy the code


Version 03 and 07

  • Version 03 uses a class called HSSFWorkbook to manipulate Excel data in version 03
  • Version 07 uses a class called XSSFWorkbook to manipulate Excel data in 2007

In fact, their methods are the same, just different classes. And which object to use, we can determine which object to create based on the suffix.


	@Test
	public void testRead03And07Excel(a) throws Exception {
		String fileName = "D: \ \ itcast \ \ test. XLSX." ";
		if(fileName.matches("^. + \ \. (? i)((xls)|(xlsx))$")) {// Check if it is an Excel document
			
			boolean is03Excel = fileName.matches("^. + \ \. (? i)(xls)$");
			
			FileInputStream inputStream = new FileInputStream(fileName);
			
			// read the workbook
			Workbook workbook = is03Excel ?new HSSFWorkbook(inputStream):new XSSFWorkbook(inputStream);
			// select * from worksheet 1
			Sheet sheet = workbook.getSheetAt(0);
			//3. Read line 3
			Row row = sheet.getRow(2);
			//4. Read row 3 column 3
			Cell cell = row.getCell(2);
			System.out.println("The contents of the cell in row 3, column 3 are:"+ cell.getStringCellValue()); workbook.close(); inputStream.close(); }}Copy the code

Excel style

Back to our requirements, Excel should look good when we export data using POI. Similar to the following template:

In the POI, you can use formatting objects to format Excel documents; That is, styling excel content.

The main formatting objects used in POI are:

  • Merged cell
  • Set the cell style
    • Set the cell font
    • In the middle
    • Background color and so on

The style object of the POI is obviously property workbook. Apply to worksheets


Merged cell

Belongs to a workbook and applies to a worksheet

The merged cell object is created with four parameters:

  • Start position of row
  • End position of line
  • The starting position of the column
  • The end position of the column

    @Test
    public void testCellRange(a) throws IOException {

        // Create a workbook
        HSSFWorkbook workbook = new HSSFWorkbook();

        // Create merged cell objects, starting from row 6 through 10, starting from column 6 through 10
        CellRangeAddress cellRangeAddress = new CellRangeAddress(5.9.5.9);

        // Create a worksheet
        HSSFSheet sheet = workbook.createSheet("I'm the new worksheet.");

		// Apply to the worksheet
        sheet.addMergedRegion(cellRangeAddress);

        // Create row, coordinates start at 0, I create row 6
        HSSFRow row = sheet.createRow(5);

        // Create a cell with coordinates starting from 0, so row 6 and column 6
        HSSFCell cell = row.createCell(5);

        // Write data to cells
        cell.setCellValue("helloWorld");

        // Write the workbook to hard disk
        FileOutputStream outputStream = new FileOutputStream("C:\\ workbook.xls");
        workbook.write(outputStream);

        / / close the flow
        workbook.close();
        outputStream.close();

    }
Copy the code

Set the cell style

As you can see in the figure above, we have implemented merging cells, but generally we set the font to be centered, font size, and so on. The POI also provides corresponding objects for us to implement:

Set up in the middle

The style belongs to the workbook and applies to cells:

    @Test
    public void test(a) throws IOException {

        // Create a workbook
        HSSFWorkbook workbook = new HSSFWorkbook();

        // Create a style object
        HSSFCellStyle style = workbook.createCellStyle();

        // Create merged cell objects, starting from row 6 through 10, starting from column 6 through 10
        CellRangeAddress cellRangeAddress = new CellRangeAddress(5.9.5.9);

        // Set the horizontal center
        style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
        // Set vertical center
        style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);

        // Create a worksheet
        HSSFSheet sheet = workbook.createSheet("I'm the new worksheet.");

        sheet.addMergedRegion(cellRangeAddress);
        // Create row, coordinates start at 0, I create row 6
        HSSFRow row = sheet.createRow(5);

        // Create a cell with coordinates starting from 0, so row 6 and column 6
        HSSFCell cell = row.createCell(5);

        // Write data to cells
        cell.setCellValue("helloWorld");

        // Set the style of the cell
        cell.setCellStyle(style);

        // Write the workbook to hard disk
        FileOutputStream outputStream = new FileOutputStream("C:\\ workbook.xls");
        workbook.write(outputStream);

        / / close the flow
        workbook.close();
        outputStream.close();

    }

Copy the code

Set the font

Fonts belong to the workbook and are applied to styles.


    @Test
    public void test(a) throws IOException {

        // Create a workbook
        HSSFWorkbook workbook = new HSSFWorkbook();

        // Create a style object
        HSSFCellStyle style = workbook.createCellStyle();

        // Create merged cell objects, starting from row 6 through 10, starting from column 6 through 10
        CellRangeAddress cellRangeAddress = new CellRangeAddress(5.9.5.9);

        // Set the horizontal center
        style.setAlignment(HSSFCellStyle.ALIGN_CENTER);
        // Set vertical center
        style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);

        // Create a font object
        HSSFFont font = workbook.createFont();

        // Set the font to bold
        font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
        // The font is 23 points
        font.setFontHeightInPoints((short) 23);
        // Set the font color
        font.setColor(HSSFFont.COLOR_RED);

        // The font applies to the style
        style.setFont(font);

        // Create a worksheet
        HSSFSheet sheet = workbook.createSheet("I'm the new worksheet.");

        sheet.addMergedRegion(cellRangeAddress);
        // Create row, coordinates start at 0, I create row 6
        HSSFRow row = sheet.createRow(5);

        // Create a cell with coordinates starting from 0, so row 6 and column 6
        HSSFCell cell = row.createCell(5);

        // Write data to cells
        cell.setCellValue("helloWorld");

        // Set the style of the cell
        cell.setCellStyle(style);

        // Write the workbook to hard disk
        FileOutputStream outputStream = new FileOutputStream("C:\\ workbook.xls");
        workbook.write(outputStream);

        / / close the flow
        workbook.close();
        outputStream.close();

    }
Copy the code


Implement export function #

Bind the button event to request the Action to handle the export and open an input box for the user to download

        function doExportExcel() {
            window.open("${basePath}user/user_exportExcel.action");   
        }

Copy the code

The Action to deal with

    / * * * * * * * * * * * * export Excel * * * * * * * * * * * * * * * * * * * * * * * * * /
    public void exportExcel(a) throws IOException {

        // Find all the data in the list
        List<User> list = userServiceImpl.findObjects();

        // Export is simply an Excel file that the user can download
        HttpServletResponse response = ServletActionContext.getResponse();

        // Set the header and specify the name
        response.setHeader("Content-Disposition"."attachment; filename=" + URLEncoder.encode("List display.xls"."UTF-8"));
        // Specify the class capacity data to return
        response.setContentType("application/x-execl");

        ServletOutputStream outputStream = response.getOutputStream();

        // Export Excel to Service layer
        userServiceImpl.exportExcel(list, outputStream);

    }

Copy the code

The Service implementation


    /** * the first line is dead, font size 11, centered, bold, merge cells * the second line is dead, bold * the third line starts, is the database list of data */
    @Override
    public void exportExcel(List<User> list, ServletOutputStream outputStream) {

        /*********** Create workbook -- Style -- Font -- cell *************/
        HSSFWorkbook workbook = new HSSFWorkbook();

        // Merge cells in the first row
        CellRangeAddress cellRangeAddress = new CellRangeAddress(0.0.0.4);

        // Create the first line style.
        HSSFCellStyle cellStyle = workbook.createCellStyle();
        cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
        cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);

        // Create a second line style.
        HSSFCellStyle cellStyle2 = workbook.createCellStyle();
        cellStyle2.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
        cellStyle2.setAlignment(HSSFCellStyle.ALIGN_CENTER);

        // Create the first line of font
        HSSFFont font = workbook.createFont();
        font.setFontHeightInPoints((short) 23);
        font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);

        // Create the second line font
        HSSFFont font2 = workbook.createFont();
        font2.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);

        // The font applies to the style
        cellStyle.setFont(font);
        cellStyle2.setFont(font2);

        /*********** Create a worksheet *************/
        HSSFSheet sheet = workbook.createSheet("User List");

        // The first row of cells applies to the worksheet
        sheet.addMergedRegion(cellRangeAddress);

        // Set the default column width
        sheet.setDefaultColumnWidth(25);

        /*********** Create a row *************/
        / / the first line
        HSSFRow row = sheet.createRow(0);
        HSSFCell cell = row.createCell(0);
        cell.setCellStyle(cellStyle);
        cell.setCellValue("User List");

        // The second line of data is also written dead, we can use the array traversal
        String[] data = {"Username"."Account"."Department"."Gender"."E-mail"};
        HSSFRow row1 = sheet.createRow(1);
        for (int i = 0; i < data.length; i++) {
            HSSFCell cell1 = row1.createCell(i);
            cell1.setCellValue(data[i]);

            // Load the second line style
            cell1.setCellStyle(cellStyle2);

        }


        /*************** Don't repeat rows and columns as you loop. Otherwise, an error will be reported !!!! * * * * * * * * * * * * * * * * * /
        // The third row of data is the data stored in our database

        if(list ! =null) {
            int i=2;
            for (User user : list) {

                // Start at line 3
                HSSFRow row2 = sheet.createRow(i);

                HSSFCell row2Cel0 = row2.createCell(0);
                row2Cel0.setCellValue(user.getName());

                HSSFCell row2Cell = row2.createCell(1);
                row2Cell.setCellValue(user.getAccount());

                HSSFCell row2Cel2 = row2.createCell(2);
                row2Cel2.setCellValue(user.getDept());

                HSSFCell row2Cel3 = row2.createCell(3);
                row2Cel3.setCellValue(user.isGender() ? "Male" : "Female");

                HSSFCell row2Cel4 = row2.createCell(4); row2Cel4.setCellValue(user.getEmail()); i++; }}try {
            // Write to outputSteam
            workbook.write(outputStream);

            workbook.close();
            outputStream.close();

        } catch(IOException e) { e.printStackTrace(); }}Copy the code

The effect


Optimization of a

Let’s look at the following code. They all have to be centered except for the size of the font. Everything else is the same. It takes up so much code!!


        // Create the first line style.
        HSSFCellStyle cellStyle = workbook.createCellStyle();
        cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
        cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);

        // Create a second line style.
        HSSFCellStyle cellStyle2 = workbook.createCellStyle();
        cellStyle2.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
        cellStyle2.setAlignment(HSSFCellStyle.ALIGN_CENTER);

        // Create the first line of font
        HSSFFont font = workbook.createFont();
        font.setFontHeightInPoints((short) 23);
        font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);

        // Create the second line font
        HSSFFont font2 = workbook.createFont();
        font2.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);

        // The font applies to the style
        cellStyle.setFont(font);
        cellStyle2.setFont(font2);
Copy the code

So I extract a method to get the style

  • A workbook is required to create styles
  • Only the font size changes

    / * * *@paramWorkbook currently uses workbook *@paramFontSize fontSize * * */
    public HSSFCellStyle createStyle(HSSFWorkbook workbook, short fontSize) {

        HSSFCellStyle cellStyle = workbook.createCellStyle();
        cellStyle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
        cellStyle.setAlignment(HSSFCellStyle.ALIGN_CENTER);

        HSSFFont font = workbook.createFont();
        font.setFontHeightInPoints(fontSize);
        font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);
        cellStyle.setFont(font);

        return cellStyle;
    }
Copy the code

When used, the code is called like this:

        HSSFCellStyle cellStyle = createStyle(workbook, (short) 24);
        HSSFCellStyle cellStyle2 = createStyle(workbook, (short) 13);
	
Copy the code

Optimization of two

Our Service business layer seems to have too much code. This makes it inconvenient for us to maintain.

What I do is: extract the code into Utils methods and call the Service layer.


Implement import function

Now I have this Excel file, and I want to store the information in the database and display it in the browser

In fact, importing Excel is like uploading a file, but instead of saving the file on the server’s hard drive, you save it in a database and export it to the browser.

        function doImportExcel() {
            document.forms[0].action = "${basePath}user/user_importExcel.action";
            document.forms[0].submit();

        }

Copy the code

Action Encapsulates file upload

/ * * * * * * * * * * * * * upload Excel * * * * * * * * * * * * * * * * * * * * * * * * /
    private File userExcel;
    private String userExcelFileName;
    private String userExcelContentType;

    public void setUserExcel(File userExcel) {
        this.userExcel = userExcel;
    }

    public void setUserExcelFileName(String userExcelFileName) {
        this.userExcelFileName = userExcelFileName;
    }

    public void setUserExcelContentType(String userExcelContentType) {
        this.userExcelContentType = userExcelContentType;
    }


Copy the code

The Action to deal with

Mainly determine whether to upload files. The Service layer


    / * * * * * * * * * * * * import Excel * * * * * * * * * * * * * * * * * * * * * * * * * /
    public String importExcel(a) throws IOException {

        // get the excel file
        if(userExcel ! =null) {// Is it excel
            if(userExcelFileName.matches("^. + \ \. (? i)((xls)|(xlsx))$")) {/ / 2, importuserServiceImpl.importExcel(userExcel, userExcelFileName); }}return "list";
    }
Copy the code

Utils returns wrapped as a collection


 public static List<User> importExcel(File userExcel, String userExcelFileName) {

        try {
            FileInputStream fileInputStream = new FileInputStream(userExcel);
            boolean is03Excel = userExcelFileName.matches("^. + \ \. (? i)(xls)$");
            // read the workbook
            Workbook workbook = is03Excel ? new HSSFWorkbook(fileInputStream) : new XSSFWorkbook(fileInputStream);
            //2
            Sheet sheet = workbook.getSheetAt(0);
            //3
 			List<User> users = new ArrayList<>();
            if (sheet.getPhysicalNumberOfRows() > 2) {
                User user = null;
                for (int k = 2; k < sheet.getPhysicalNumberOfRows(); k++) {
                    //4, read the cell
                    Row row = sheet.getRow(k);
                    user = new User();
                    / / user name
                    Cell cell0 = row.getCell(0);
                    user.setName(cell0.getStringCellValue());
                    / / account
                    Cell cell1 = row.getCell(1);
                    user.setAccount(cell1.getStringCellValue());
                    // Department
                    Cell cell2 = row.getCell(2);
                    user.setDept(cell2.getStringCellValue());
                    / / gender
                    Cell cell3 = row.getCell(3);
                    user.setGender(cell3.getStringCellValue().equals("Male"));
                    / / cell phone number
                    String mobile = "";
                    Cell cell4 = row.getCell(4);
                    try {
                        mobile = cell4.getStringCellValue();
                    } catch (Exception e) {
                        double dMobile = cell4.getNumericCellValue();
                        mobile = BigDecimal.valueOf(dMobile).toString();
                    }
                    user.setMobile(mobile);

                    // Email address
                    Cell cell5 = row.getCell(5);
                    user.setEmail(cell5.getStringCellValue());
                    / / birthday
                    Cell cell6 = row.getCell(6);
                    if(cell6.getDateCellValue() ! =null) {
                        user.setBirthday(cell6.getDateCellValue());
                    }
                    // The default password is 123456
                    user.setPassword("123456");
                    // The default user status is valid
                    user.setState(User.USER_STATE_VALID);

                    users.add(user);

                }
            }
            workbook.close();
            fileInputStream.close();
			return users;

        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;

    }
Copy the code

Service call


    public void importExcel(File userExcel, String userExcelFileName) {
        List<User> users = ExcelUtils.importExcel(userExcel, userExcelFileName);
        for(User user : users) { save(user); }}Copy the code

conclusion

  • Import means that users upload an Excel file, we read the data of the Excel file, encapsulate it into objects, and store it in the database
  • Exporting means writing our database data to Excel files for users to download
    • Specify that our return type is Excel
  • Worksheets belong to workbooks, rows belong to worksheets, and cells belong to rows
  • In the POI component, we divided Excel files into two categories, version 03 and version 07, which correspond to different objects, but the API of both objects is the same. Therefore, we can determine which object to use by the suffix of the file
  • Our Excel should have some style to look good. The POI also provides a corresponding API for us to modify the style
    • Merge cells, subordinate to workbooks, applications, and worksheets
    • Setting the center and font size are style specific. Belongs to workbooks, applications and cells.

If you find this article helpful, give the author a little encouragement