1. 程式人生 > >SpringBoot加Poi仿照EasyPoi實現Excel導出

SpringBoot加Poi仿照EasyPoi實現Excel導出

coder 地址 屬性 pre ice tle sele boot excel表

POI提供API給Java程序對Microsoft Office格式檔案讀和寫的功能,詳細功能可以直接查閱API,因為使用EasyPoi過程中總是缺少依賴,沒有搞明白到底是什麽坑,索性自己寫一個簡單工具類,來實現無論傳入任何對象集合,都能夠實現導出Excel的功能,沒有看EasyPoi的源碼, 只是在功能上模仿一下。

首先導入基本依賴,除了SpringBoot基本依賴依賴,導入Poi的依賴

<!-- https://mvnrepository.com/artifact/org.apache.poi/poi -->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>3.17
</version> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml --> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>3.17</version> </dependency>

編寫自定義註解

@Retention(RetentionPolicy.RUNTIME)
public @interface Excel {
    
//Excel列名稱 String name()
default "";
//Excel列數
int orderNum() default 0; }

編寫javaBean,所有需要導出的屬性都使用Excel註解

public class Person{


   private String id;


   @Excel(name = "用戶姓名")
    private String userName;

    @Excel(name 
= "電話",orderNum = 1) private String phone; @Excel(name = "郵箱",orderNum = 2) private String email; @Excel(name = "地址",orderNum = 3) private String address; public void setId(String id){ this.id=id; } public String getId(){ return id; } public void setUserName(String userName){ this.userName=userName; } public String getUserName(){ return userName; } public void setphone(String phone){ this.phone=phone; } public String getphone(){ return phone; } public void setEmail(String email){ this.email=email; } public String getEmail(){ return email; } public void setAddress(String address){ this.address=address; } public String getAddress(){ return address; } }

編寫工具類

public class PoiUtils {


    /**
     *
     * 功能描述:
     * 需要導出的屬性要加Excel註解,實現Excel導出功能
     * @param: [list, fileName, sheetName, response, clazz]
     * @return: void
     * @auther: wang
     * @date: 2019/1/18 15:31
     */
    public Static <T> void export(Collection<T> collection, String fileName, String sheetName, HttpServletResponse response, Class<?> clazz) throws IOException, IntrospectionException, InvocationTargetException, IllegalAccessException {

        HSSFWorkbook workbook = new HSSFWorkbook();
        //創建一個Excel表單,參數為sheet的名字
        HSSFSheet sheet = workbook.createSheet(sheetName);
        //創建表頭
        setTitle(workbook, sheet, clazz);
        //新增數據行,並且設置單元格數據
        int rowNum = 1;
        for (T t : collection) {
            HSSFRow row = sheet.createRow(rowNum);
            Field[] fields = clazz.getDeclaredFields();
            for (Field field : fields) {
                if (field.isAnnotationPresent(Excel.class)) {
                    PropertyDescriptor pd = new PropertyDescriptor(field.getName(),
                            clazz);
                    Method getMethod = pd.getReadMethod();//獲得get方法
                    Excel excel = field.getAnnotation(Excel.class);
                    row.createCell(excel.orderNum()).setCellValue(String.valueOf(getMethod.invoke(t)));

                }

            }
            rowNum++;
        }
        //清空response
        response.reset();
        // 告訴瀏覽器用什麽軟件可以打開此文件
        response.setHeader("content-Type", "application/vnd.ms-excel");
        // 下載文件的默認名稱
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName + ".xls", "utf-8"));
        OutputStream os;
        //可以將生成Excel默認下載到某個目錄下
        //os = new BufferedOutputStream(new FileOutputStream("D:\\bmj\\target\\bmj128-0.0.1\\" + fileName));
//也可以通過response得到輸出流,寫到輸出流中,在頁面中進行下載 os = new BufferedOutputStream(response.getOutputStream()); //將excel寫入到輸出流中 workbook.write(os); os.flush(); os.close(); } /*** * 設置表頭 * @param workbook * @param sheet */ private static void setTitle(HSSFWorkbook workbook, HSSFSheet sheet, Class clazz) { HSSFRow row = sheet.createRow(0); Field[] fields = clazz.getDeclaredFields(); //設置為居中加粗 HSSFCellStyle style = workbook.createCellStyle(); HSSFFont font = workbook.createFont(); //設置字體 font.setFontName("宋體"); //設置粗體 font.setBold(true); //設置字號 font.setFontHeightInPoints((short) 14); //設置顏色 font.setColor(IndexedColors.BLACK.index); style.setFont(font); HSSFCell cell; for (Field field : fields) { if (field.isAnnotationPresent(Excel.class)) { Excel excel = field.getAnnotation(Excel.class); cell = row.createCell(excel.orderNum()); cell.setCellValue(excel.name()); cell.setCellStyle(style); sheet.setColumnWidth(excel.orderNum(), 30*256); } } } }

頁面調用,頁面采用的是EasyUI框架

      <div style="padding:5px;background:#fafafa;width:100%;">
            <a href="javascript:void(0)" class="easyui-linkbutton" plain="true" iconCls="icon-undo"  onclick="downLoadExcel()">導出日誌</a>
      </div>

可以按照頁面給增加篩選條件,根據篩選條件下載

   function downLoadExcel(){

        var url=base+/api/xx?xx=+$("#xx").val()+&xx=+$("#xx").val()+&xx=+$("#xx").val();
        window.location.href = url;

    }

編寫Controller

@RestController
@RequestMapping(value = "/api/xx")
public class PersonController {

    private static final Logger LOG = LoggerFactory.getLogger(PersonController .class);
    @Resource(name = "personService")
    private PersonService personService;



    @RequestMapping("/export")
    public void export(PersonQuery personQuery, HttpServletResponse response) {

        List<Person> personList = personService.selectAll(personQuery);

        try {
            PoiUtils.export(auditLogList, "審計日誌", "審計日誌", response,AuditLog.class);
        } catch (IOException | IntrospectionException | InvocationTargetException | IllegalAccessException e) {
           LOG.error("審計日誌錯誤{}",e);
        }

    }


}

頁面如下

技術分享圖片

點擊導出日誌,顯示如下

技術分享圖片

目前僅僅是針對單個sheet的操作,也沒有像合並單元格這種復雜操作,需要繼續完善。

SpringBoot加Poi仿照EasyPoi實現Excel導出