国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

springboot項(xiàng)目實(shí)現(xiàn)excel導(dǎo)出

這篇具有很好參考價(jià)值的文章主要介紹了springboot項(xiàng)目實(shí)現(xiàn)excel導(dǎo)出。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

項(xiàng)目中經(jīng)常會(huì)有列表查詢(xún),然后導(dǎo)出excel的功能,以下是其中一種方法,簡(jiǎn)單寫(xiě)個(gè)Demo
,先看項(xiàng)目結(jié)構(gòu):
springboot項(xiàng)目實(shí)現(xiàn)excel導(dǎo)出

  1. pom.xml
	<properties>
        <spring-boot.version>2.3.12.RELEASE</spring-boot.version>
    </properties>

    <dependencies>
        <!--注意:由于 spring-boot-starter-web 默認(rèn)替我們引入了核心啟動(dòng)器 spring-boot-starter,
        因此,當(dāng) Spring Boot  項(xiàng)目中的 pom.xml 引入了 spring-boot-starter-web 的依賴(lài)后,
        就無(wú)須在引入 spring-boot-starter 核心啟動(dòng)器的依賴(lài)了-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>${spring-boot.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <version>${spring-boot.version}</version>
            <scope>test</scope>
        </dependency>

        <!--整合mytais-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.3</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.6</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.20</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.16</version>
            <scope>compile</scope>
        </dependency>

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.9</version>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.12.3</version>
        </dependency>
        
        <!--excel-->
        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi-ooxml</artifactId>
            <version>4.1.2</version>
        </dependency>

        <!--excel2003版本要引入此包-->
<!--        <dependency>
            <groupId>org.apache.poi</groupId>
            <artifactId>poi</artifactId>
            <version>4.1.2</version>
        </dependency>-->
    </dependencies>

其他依賴(lài)就不提了,主要就只這個(gè)依賴(lài)org.apache.poi.poi-ooxml
說(shuō)明:

poi是Apache旗下的一個(gè)開(kāi)源項(xiàng)目,由Apache官方維護(hù),poi有兩個(gè)不同的jar包,分別是處理excel2003和excel2007+的,對(duì)應(yīng)的是poi和poi-ooxml。畢竟poi-ooxml是poi的升級(jí)版本,處理的單頁(yè)數(shù)據(jù)量也是百萬(wàn)級(jí)別的,所以我們選擇的也是poi-ooxml。

  1. application.yml
spring:
  datasource:
      driverClassName: com.mysql.jdbc.Driver
      url: jdbc:mysql://192.168.233.136:3306/mydata?zeroDateTimeBehavior=convertToNull&useUnicode=true&characterEncoding=utf8&allowMultiQueries=true
      username: root
      password: 123456
mybatis:
  mapperLocations: classpath*:mapper/*Mapper.xml
  # 打印sql語(yǔ)句
  logging:
    level:
      com.meng.user: debug
  1. Excel2Application
@SpringBootApplication
@MapperScan("com.meng.dao")
public class Excel2Application {
    public static void main(String[] args) {
        SpringApplication.run(Excel2Application.class  , args);
    }
}
  1. entity
@Data
public class BaiDuResult {
    private Long id;

    /**
     *標(biāo)題
     */
    private String title;

    /**
     *內(nèi)容
     */
    private String content;

    /**
     *內(nèi)容來(lái)源
     */
    private String sourceUrl;

    /**
     *封面圖片
     */
    private String imgUrl;

    /**
     *創(chuàng)建時(shí)間
     */
    private Date createTime;

    /**
     *更新時(shí)間
     */
    private Date updateTime;

    /**
     *是否刪除
     */
    private Byte delFlag;

}
  1. dao
@Repository
public interface BaiDuResultDao {

    List<BaiDuResult> findAllPage(@Param("start") int start , @Param("pageSize")int pageSize);
  1. BaiDuResultMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.meng.dao.BaiDuResultDao" >
  <resultMap id="BaseResultMap" type="com.meng.entity.BaiDuResult" >
    <id column="id" property="id" jdbcType="BIGINT" />
    <result column="title" property="title" jdbcType="VARCHAR" />
    <result column="content" property="content" jdbcType="VARCHAR" />
    <result column="source_url" property="sourceUrl" jdbcType="VARCHAR" />
    <result column="img_url" property="imgUrl" jdbcType="VARCHAR" />
    <result column="create_time" property="createTime" jdbcType="TIMESTAMP" />
    <result column="update_time" property="updateTime" jdbcType="TIMESTAMP" />
    <result column="del_flag" property="delFlag" jdbcType="TINYINT" />
  </resultMap>
  <sql id="Base_Column_List" >
    id, title, content, source_url, img_url, create_time, update_time, del_flag
  </sql>
  
  <select id="findAllPage" resultMap="BaseResultMap">
    select
    <include refid="Base_Column_List" />
    from result limit #{start} , #{pageSize}
  </select>
  1. service
@Service
public class ResultService {

    @Autowired
    private BaiDuResultDao dao;

    public Workbook exportToExcel(){
        //這是表頭
        String[] arr = {"ID","標(biāo)題","內(nèi)容","內(nèi)容來(lái)源","封面圖片","創(chuàng)建時(shí)間","更新時(shí)間","是否刪除"};
        //這是具體數(shù)據(jù)
        List<BaiDuResult> list = dao.findAllPage(0, 1000);
        Workbook workbook = ExcelUtil.writeToExcelByList(arr, list , BaiDuResult.class);
        return workbook;
    }
}
  1. controller
@RestController
public class ResultController {

    @Autowired
    private ResultService resultService;

    @GetMapping("/export")
    public void exportResult(HttpServletResponse response) throws IOException {
        Workbook wb = resultService.exportToExcel();
        OutputStream output = response.getOutputStream();
        String fileName = "結(jié)果表.xlsx";
        try {
            fileName = URLEncoder.encode(fileName, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        response.setHeader("Content-disposition", "attachment;filename=" + fileName + ";" + "filename*=utf-8''" + fileName);
        wb.write(output);
        output.close();
    }
}
  1. ExcelUtils
    以上都不重要,重要的是這個(gè)工具類(lèi)的方法
public class ExcelUtil{

    public static <T> Workbook writeToExcelByList(String[] array, List<T> list , Class<T> clazz) {
        //創(chuàng)建工作薄
        Workbook wb = new XSSFWorkbook();
        //標(biāo)題和頁(yè)碼
        CellStyle titleStyle = wb.createCellStyle();
        // 設(shè)置單元格對(duì)齊方式,水平居左
        titleStyle.setAlignment(HorizontalAlignment.LEFT);
        //單元格邊框
        titleStyle.setBorderTop(BorderStyle.THIN);
        titleStyle.setBorderLeft(BorderStyle.THIN);
        titleStyle.setBorderRight(BorderStyle.THIN);
        titleStyle.setBorderBottom(BorderStyle.THIN);
        // 設(shè)置字體樣式
        Font titleFont = wb.createFont();
        // 字體高度
        titleFont.setFontHeightInPoints((short) 12);
        // 字體樣式
        titleFont.setFontName("黑體");
        titleStyle.setFont(titleFont);
        //創(chuàng)建sheet
        Sheet sheet = wb.createSheet("接入詳情");
        // 自動(dòng)設(shè)置寬度
        sheet.autoSizeColumn(0);
        // 在sheet中添加標(biāo)題行// 行數(shù)從0開(kāi)始
        Row row = sheet.createRow(0);
        for (int i = 0; i < array.length; i++) {
            Cell cell = row.createCell(i);
            cell.setCellValue(array[i]);
            cell.setCellStyle(titleStyle);
        }
        // 數(shù)據(jù)樣式 因?yàn)闃?biāo)題和數(shù)據(jù)樣式不同 需要分開(kāi)設(shè)置 不然會(huì)覆蓋
        CellStyle dataStyle = wb.createCellStyle();
        //單元格邊框
        dataStyle.setBorderTop(BorderStyle.THIN);
        dataStyle.setBorderLeft(BorderStyle.THIN);
        dataStyle.setBorderRight(BorderStyle.THIN);
        dataStyle.setBorderBottom(BorderStyle.THIN);
        // 設(shè)置居中樣式,水平居中
        dataStyle.setAlignment(HorizontalAlignment.CENTER);
        //數(shù)據(jù)從序號(hào)1開(kāi)始
        try {
            int index = 1;
            Field[] fields = clazz.getDeclaredFields();
            for (T t : list) {
                // 默認(rèn)的行數(shù)從0開(kāi)始,為了統(tǒng)一格式設(shè)置從1開(kāi)始,就是從excel的第二行開(kāi)始
                row = sheet.createRow(index);
                for (int i = 0; i < fields.length; i++) {
                    // 默認(rèn)的行數(shù)從0開(kāi)始,為了統(tǒng)一格式設(shè)置從1開(kāi)始,就是從excel的第二行開(kāi)始
                    Cell cell = row.createCell(i);
                    // 為當(dāng)前列賦值
                    Field field = fields[i];
                    if (!field.isAccessible()) {
                        field.setAccessible(true);
                    }
                    Object value = (new PropertyDescriptor(field.getName(), clazz)).getReadMethod().invoke(t);
                    setValue(cell , value);
                    //設(shè)置數(shù)據(jù)的樣式
                    cell.setCellStyle(dataStyle);
                }
                index++;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return wb;
    }

    /**
     * 設(shè)置cellValue
     * 這里可以根據(jù)value的類(lèi)型,進(jìn)行格式化,比如日期格式化
     */
    private static void setValue(Cell cell , Object value){
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        if(value != null && !"".equals(value)){
            if(value instanceof Date){
                cell.setCellValue(dateFormat.format(value));
            }else{
                cell.setCellValue(value.toString());
            }
        }
    }
}

這個(gè)writeToExcelByList,是利用反射,獲取class的fields,然后循環(huán)遍歷插入到cell,這里可以自定義Annotation,然后進(jìn)行一些自定義的操作,比如日期格式化、該field是否導(dǎo)出到excel中等,這里只做簡(jiǎn)單的演示

  1. 導(dǎo)出結(jié)果
    springboot項(xiàng)目實(shí)現(xiàn)excel導(dǎo)出
    這里的單元格寬度應(yīng)該是可以設(shè)置的,但我就不研究了,有需要再說(shuō)

本文是采用Apache的開(kāi)源項(xiàng)目poi來(lái)實(shí)現(xiàn)的,這個(gè)在企業(yè)中應(yīng)用較多(個(gè)人觀點(diǎn)),還有一個(gè)EasyExcel項(xiàng)目,是alibaba出的,看起來(lái)也不錯(cuò),但我就不嘗試了,放個(gè)鏈接 簡(jiǎn)潔、快速、節(jié)約內(nèi)存的Excel處理工具EasyExcel ,或者直接去官網(wǎng)看文檔吧,更清楚 EasyExcel官方文檔 - 基于Java的Excel處理工具 | Easy Excel

本文參考:Spring boot實(shí)現(xiàn)Excel導(dǎo)出文件

大數(shù)據(jù)量的處理

首先介紹一下目前導(dǎo)出excel的幾種格式:Excel 2003、Excel 2007

Excel 2003:在POI中使用HSSF對(duì)象時(shí),excel 2003最多只允許存儲(chǔ)65536條數(shù)據(jù),一般用來(lái)處理較少的數(shù)據(jù)量。這時(shí)對(duì)于百萬(wàn)級(jí)別數(shù)據(jù),Excel肯定容納不了。

Excel 2007:當(dāng)POI升級(jí)到XSSF對(duì)象時(shí),它可以直接支持excel2007以上版本,因?yàn)樗捎胦oxml格式。這時(shí)excel可以支持1048576條數(shù)據(jù),單個(gè)sheet表就支持近104萬(wàn)條數(shù)據(jù)了,雖然這時(shí)導(dǎo)出100萬(wàn)數(shù)據(jù)能滿足要求,但使用XSSF測(cè)試后發(fā)現(xiàn)偶爾還是會(huì)發(fā)生堆溢出,所以也不適合百萬(wàn)數(shù)據(jù)的導(dǎo)出。

在POI3.8之后新增加了一個(gè)類(lèi),SXSSFWorkbook,采用當(dāng)數(shù)據(jù)加工時(shí)不是類(lèi)似前面版本的對(duì)象,

它可以控制excel數(shù)據(jù)占用的內(nèi)存,他通過(guò)控制在內(nèi)存中的行數(shù)來(lái)實(shí)現(xiàn)資源管理,即當(dāng)創(chuàng)建對(duì)象超過(guò)了設(shè)定的行數(shù),

它會(huì)自動(dòng)刷新內(nèi)存,將數(shù)據(jù)寫(xiě)入文件,這樣導(dǎo)致打印時(shí),占用的CPU,和內(nèi)存很少。

所以可以使用SXXFWorkBook來(lái)實(shí)現(xiàn)百萬(wàn)級(jí)別數(shù)據(jù)量的導(dǎo)出。
只要將上文中的Workbook,替換成SXSSFWorkbook即可
springboot項(xiàng)目實(shí)現(xiàn)excel導(dǎo)出
這里參考: Java 使用POI 導(dǎo)出 百萬(wàn)級(jí)別的數(shù)據(jù)量的 Excel

大數(shù)據(jù)量的處理二

其實(shí)上文的大數(shù)據(jù)量處理方式有個(gè)問(wèn)題,比如我要從數(shù)據(jù)庫(kù)查詢(xún)100萬(wàn)的數(shù)據(jù),然后導(dǎo)出到excel,這個(gè)查詢(xún)的過(guò)程(包括數(shù)據(jù)處理的過(guò)程)是很漫長(zhǎng)的,等處理完,頁(yè)面才會(huì)彈出下載彈窗,可能要等待十幾秒甚至幾十秒,不知情的用戶還以為是系統(tǒng)異常了,也就是說(shuō)不能快速響應(yīng),至少我還沒(méi)找到快速響應(yīng)的方式

那么還有另一種方式解決這個(gè)問(wèn)題,就是使用csv文件替代表格(csv可以和表格互相轉(zhuǎn)換且使用效果基本相同)。csv格式文件和txt文件一樣理論上沒(méi)有大小上限,這種方式就不需要poi的依賴(lài)了。

直接上代碼:

entity加上toString方法:

    @Override
    public String toString() {
        return id +
                "," + title +
                "," + content  +
                "," + sourceUrl  +
                "," + imgUrl +
                "," + createTime +
                "," + updateTime +
                "," + delFlag;
    }
@RestController
public class ResultController {

    @Autowired
    private BaiDuResultDao dao;

    @GetMapping("/export")
    public void exportResult(HttpServletResponse response){

        try {
            response.reset();
            response.setContentType("application/csv;charset=GBK");
            response.setHeader("Content-Disposition","attachment;filename=file" + System.currentTimeMillis() + ".csv");
            response.setCharacterEncoding("GBK");
            PrintWriter out = response.getWriter();
            out.println("id,標(biāo)題,內(nèi)容,內(nèi)容來(lái)源,封面圖片,創(chuàng)建時(shí)間,更新時(shí)間,是否刪除");
            int limit = 100000;
            int pageSize = 10000;
            for (int i = 0; i < limit; i++) {
                List<BaiDuResult> list = dao.findAllPage(i, pageSize);
                for (BaiDuResult baiDuResult : list) {
                    String str = baiDuResult.toString();
                    out.println(str);
                }
                i += pageSize;
            }
            out.flush();
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

這里可以看到,這里可以用分頁(yè)的方式,將每次分頁(yè)結(jié)果直接響應(yīng)給頁(yè)面,也就是用戶點(diǎn)擊下載,立馬彈窗,然后下載的過(guò)程就耗時(shí)較長(zhǎng)了,這樣用戶的交互會(huì)好一些。

但是?。。。。。?/strong> csv文件會(huì)比excel文件大很多很多,完全不在一個(gè)數(shù)量級(jí),因?yàn)閏sv可以用記事本打開(kāi),本質(zhì)上是字符串文件,沒(méi)有任何壓縮,xls之類(lèi)的都是有壓縮的,需要專(zhuān)門(mén)軟件打開(kāi)

參考:java實(shí)現(xiàn)大數(shù)據(jù)Excel導(dǎo)出文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-477903.html

到了這里,關(guān)于springboot項(xiàng)目實(shí)現(xiàn)excel導(dǎo)出的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包