Springboot integrates POI to realize Excel report examples everywhere

1. POI Introduction

For details, please refer to this article
https://blog.csdn.net/w893932747/article/details/89354979

2. POI implementation export example

Let's write an interface example of integrating poi to export excel files in a springboot project

1. Environment preparation

Prepare a springboot project first, I will not give an example here
Introduce poi dependencies under the springboot project, here is the 3.17 version as an example

<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi</artifactId>
    <version>3.17</version>
</dependency>
<dependency>
    <groupId>org.apache.poi</groupId>
    <artifactId>poi-ooxml</artifactId>
    <version>3.17</version>
</dependency>

For data preparation, we export the following data as a report
insert image description here
data report sql file:
https://pan.baidu.com/s/1bv0EV1fIhbExD6j0dhlzPw extraction code 8qz1

2. Create dao layer

  1. Entity class
public class GoodInfo {
    
    
    private Long spuId;
    private String title;
    private String cname;
    private String brandName;
    private String skuId;
    private String subTitle;
    private String ownSpec;
    private Double price;

    /*Getter Setter自行添加*/
  1. Dao class (here the query sql is written in the way of annotation)
import com.changgou.item.po.GoodInfo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;

@Mapper
public interface PoiDao {
    
    

    @Select("SELECT * FROM `good_info` ORDER BY spu_id LIMIT 200")
    List<GoodInfo> getGoodInfo();
}

2. Create the controller layer

import com.changgou.item.service.PoiService;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletResponse;

@Controller
@RequestMapping("poi")
public class PoiController {
    
    

    @Autowired
    private PoiService poiService;

    @PostMapping("/export")
    public ResponseEntity<Void> exportGoodInfo(HttpServletResponse response) {
    
    
        poiService.exportGoodInfo(response);
        return ResponseEntity.ok().build();
    }
}

3. Create service layer

The values ​​of the first few fields of our example data report and the last few fields have a one-to-many relationship, so we can see that the front department fields of each piece of data are the same, here we group them by the same fields in this part, and put Merge cells with department fields of the same value

import com.alibaba.fastjson.JSONObject;
import com.changgou.item.dao.PoiDao;
import com.changgou.item.po.GoodInfo;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.util.CellRangeAddress;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class PoiService {
    
    
    private final Logger LOGGER = LoggerFactory.getLogger(this.getClass());

    public static final List<String> GOOD_INFO_COLUMNS = new ArrayList<>(
            Arrays.asList("spu编号", "标题","商品分类","商品品牌","sku编号","详细信息","参数属性","价格")
    );
    public static final List<String> GOOD_COLUMNS = new ArrayList<>(
            Arrays.asList("spuId", "title","cname","brandName","skuId","subTitle","ownSpec","price")
    );

    @Autowired
    private PoiDao poiDao;

    public void exportGoodInfo(HttpServletResponse response) {
    
    
        List<GoodInfo> goodInfoList = poiDao.getGoodInfo();
        // 按spuId分组
        Map<String, List<GoodInfo>> goodInfoMap = goodInfoList.stream()
                .collect(Collectors.groupingBy(item -> item.getSpuId().toString()));
        // 创建一个空的excel表格
        HSSFWorkbook workbook = new HSSFWorkbook();
        // 创建一个sheet页
        HSSFSheet sheet = workbook.createSheet("商品信息列表");
        // 创建表头
        HSSFRow row = sheet.createRow(0);
        // 创建表头格式style对象
        HSSFCellStyle style = workbook.createCellStyle();
        // 创建字体对象
        HSSFFont font = workbook.createFont();
        //字体设置为红色
        font.setColor(IndexedColors.RED.index);
        //字体加粗
        font.setBold(true);
        style.setFont(font);
        // 设置单元格水平居中
        style.setAlignment(HorizontalAlignment.CENTER);
        // 设置单元格填充色
        style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
        style.setFillForegroundColor(IndexedColors.YELLOW.index);
        Map<Integer, Integer> columnWidthMap = new HashMap<>();
        // 写入表头
        for (int i = 0; i< GOOD_INFO_COLUMNS.size(); i++) {
    
    
            // 创建单元格
            HSSFCell cell = row.createCell(i);
            cell.setCellStyle(style);
            // 设置单元格宽度
            sheet.setColumnWidth(i, GOOD_INFO_COLUMNS.get(i).getBytes().length *256);
            // 将表头值字符长度保存到columnWidthMap中
            columnWidthMap.put(i, GOOD_INFO_COLUMNS.get(i).getBytes().length);
            // 设置表有值
            cell.setCellValue(GOOD_INFO_COLUMNS.get(i));
        }
        // 记录正文行号
        int page = 1;
        // 创建正文格式style对象
        style = workbook.createCellStyle();
        style.setAlignment(HorizontalAlignment.CENTER);
        // 遍历正文数据
        for (Map.Entry<String, List<GoodInfo>> entry : goodInfoMap.entrySet()) {
    
    
        	// 记录每组数据起始行数
            int firstRow = page;
            for (GoodInfo goodInfo : entry.getValue()) {
    
    
            	// 创建正文行
                HSSFRow goodRow = sheet.createRow(page);
                Map<String, Object> map = JSONObject.parseObject(JSONObject.toJSONString(goodInfo), Map.class);
                for (int i = 0; i< GOOD_COLUMNS.size(); i++) {
    
    
                    // 创建单元格
                    HSSFCell cell = goodRow.createCell(i);
                    cell.setCellStyle(style);
                    Object object = map.get(GOOD_COLUMNS.get(i));
                    String value = object == null ? "" : object.toString();
                   	// 设置单元格狂歌为字段值最大的宽度
                    int headerLength = columnWidthMap.get(i);
                    int valueLength = value.getBytes().length;
                    int columnWidth = headerLength > valueLength ? headerLength : valueLength;
                    columnWidthMap.put(i, columnWidth);
                    sheet.setColumnWidth(i, columnWidth * 256);
                    cell.setCellValue(value);
                }
                page++;
            }
            // 记录每组数据末尾行数
            int lastRow = firstRow + entry.getValue().size() - 1;
            // 合并相同字段的单元格
            if (firstRow < lastRow) {
    
    
                for (int j = 0; j < 4; j++) {
    
    
                    CellRangeAddress region = new CellRangeAddress(firstRow, lastRow, j, j);
                    sheet.addMergedRegion(region);
                }
            }
        }
        response.setContentType("application/vnd.ms-excel");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String fileName = new String(("goodInfoList" + sdf.format(new Date()) + ".xls"));
        try {
    
    
            OutputStream os = response.getOutputStream();
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
            workbook.write(os);
        } catch (Exception e) {
    
    
            LOGGER.error("fail: ", e);
        }
    }

}

4. Final effect display

After the following operations are completed, you can start the project and call the interface. The final report file is displayed as follows:
insert image description here

Guess you like

Origin blog.csdn.net/weixin_44947701/article/details/124994288