最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java使用EasyExcel導(dǎo)出Excel的全流程詳解

 更新時(shí)間:2025年11月13日 08:41:46   作者:代碼怪獸大大作戰(zhàn)  
在 Java 后端開發(fā)中,Excel 導(dǎo)出是非常常見的需求,涉及報(bào)表、數(shù)據(jù)分析或業(yè)務(wù)導(dǎo)出,本文將結(jié)合 阿里 EasyExcel 庫,詳細(xì)講解 Excel 導(dǎo)出流程,包括工具類設(shè)計(jì)、樣式、列寬策略、對(duì)象映射、輸出流處理,需要的朋友可以參考下

引言

在 Java 后端開發(fā)中,Excel 導(dǎo)出是非常常見的需求,涉及報(bào)表、數(shù)據(jù)分析或業(yè)務(wù)導(dǎo)出。

本文將結(jié)合 阿里 EasyExcel 庫,詳細(xì)講解 Excel 導(dǎo)出流程,包括工具類設(shè)計(jì)、樣式、列寬策略、對(duì)象映射、輸出流處理。

一、什么是 EasyExcel

EasyExcel 是阿里巴巴開源的 Java Excel 處理庫,相比 Apache POI 或 JXL:

高性能

  • 基于 SAX 流式解析和寫入,內(nèi)存占用低
  • 可以輕松處理百萬行數(shù)據(jù)導(dǎo)出,不會(huì) OOM

易用

  • 注解式對(duì)象映射(@ExcelProperty
  • 只需定義對(duì)象類即可生成 Excel 表格

樣式靈活

  • 表頭樣式、內(nèi)容樣式、列寬、合并單元格等都可自定義

Web 集成方便

  • 可以直接輸出到瀏覽器下載,無需先生成文件

適合企業(yè)后臺(tái)系統(tǒng)、報(bào)表系統(tǒng)、統(tǒng)計(jì)平臺(tái)等場景。

二、Maven 依賴安裝

pom.xml 中引入 EasyExcel:

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>4.0.3</version>
</dependency>

注意事項(xiàng):

  1. EasyExcel 依賴 JDK 1.8 及以上版本。
  2. 在實(shí)際項(xiàng)目中,如果出現(xiàn)依賴沖突或版本不兼容導(dǎo)致導(dǎo)出異常,可參考該文章進(jìn)行排查和解決:EasyExcel 依賴沖突解決方案。

三、Excel 導(dǎo)出工具類設(shè)計(jì)

3.1 設(shè)計(jì)目標(biāo)與整體架構(gòu)

ExportTool 工具類主要實(shí)現(xiàn)了兩個(gè)導(dǎo)出方式:

  1. 簡單導(dǎo)出:快速將數(shù)據(jù)列表寫入 Excel,無樣式、無列寬控制。
  2. 帶樣式導(dǎo)出:支持自定義表頭樣式、內(nèi)容樣式和列寬自適應(yīng)。

核心設(shè)計(jì)特點(diǎn)

  • 泛型支持:通過 <T> + Class<T>,工具類可導(dǎo)出任意類型的數(shù)據(jù)對(duì)象。
  • 流安全處理:通過 NoCloseOutputStream 包裝輸出流,避免 EasyExcel 自動(dòng)關(guān)閉 HttpServletResponse。
  • 策略模式:樣式、列寬分別封裝為獨(dú)立策略,便于擴(kuò)展。
  • 日志和異常管理:導(dǎo)出過程中的異常統(tǒng)一記錄并封裝為 ServiceException,方便上層調(diào)用處理。

工具類結(jié)構(gòu)可以理解為三層:

響應(yīng)流處理 → ExcelWriter 構(gòu)建 → 樣式 & 列寬策略 → 數(shù)據(jù)寫入

3.2 完整工具類:ExportTool.java

@Slf4j
public class ExportTool {
    /**
     * 導(dǎo)出 Excel 文件(簡單導(dǎo)出)
     *
     * @param dataList  導(dǎo)出的數(shù)據(jù)列表
     * @param clazz     數(shù)據(jù)類型(Excel 實(shí)體類)
     * @param fileName  導(dǎo)出的文件名(不帶擴(kuò)展名)
     * @param <T>       數(shù)據(jù)泛型
     */
    public static <T> void exportExcel(List<T> dataList, Class<T> clazz, String fileName) {
        if (dataList == null || dataList.isEmpty()) {
            log.warn("[ExportTool] 導(dǎo)出數(shù)據(jù)為空: {}", fileName);
        }

        try {
            HttpServletResponse response = WebTool.getResponse();

            // 使用復(fù)用的響應(yīng)流設(shè)置方法
            setupResponse(response, fileName + ".xlsx");

            try (ServletOutputStream out = response.getOutputStream()) {
                // 簡單導(dǎo)出,不增加樣式或列寬限制
                EasyExcel.write(out, clazz)
                        .autoCloseStream(true)
                        .sheet("數(shù)據(jù)")
                        .doWrite(dataList);
            }

            log.info("[ExportTool] 導(dǎo)出成功: {}, 共 {} 條記錄", fileName, dataList.size());
        } catch (Exception e) {
            log.error("[ExportTool] 導(dǎo)出失敗: {}", fileName, e);
            throw new ServiceException("導(dǎo)出失敗,請(qǐng)稍后重試");
        }
    }

    /**
     * 導(dǎo)出 Excel 文件(帶表頭樣式)
     *
     * @param dataList 數(shù)據(jù)列表
     * @param clazz    數(shù)據(jù)類型(Excel 實(shí)體類)
     * @param fileName 導(dǎo)出文件名(包含 .xlsx)
     * @param <T>      數(shù)據(jù)類型
     */
    public static <T> void exportExcelWithStyle(List<T> dataList, Class<T> clazz, String fileName) {
        HttpServletResponse response = WebTool.getResponse();
        try {
            // 設(shè)置響應(yīng)頭
            setupResponse(response, fileName);

            // 獲取輸出流并防止 EasyExcel 關(guān)閉響應(yīng)流
            ServletOutputStream out = response.getOutputStream();
            NoCloseOutputStream noCloseOut = new NoCloseOutputStream(out);

            // 創(chuàng)建 ExcelWriter
            ExcelWriter excelWriter = EasyExcel.write(noCloseOut, clazz)
                    // 注冊(cè)樣式策略
                    .registerWriteHandler(new HorizontalCellStyleStrategy(createHeadStyle(), createContentStyle()))
                    // 注冊(cè)列寬自適應(yīng)策略
                    .registerWriteHandler(createAutoWidthStrategy())
                    .build();

            // 創(chuàng)建 Sheet
            WriteSheet writeSheet = EasyExcel.writerSheet("導(dǎo)出數(shù)據(jù)").build();

            // 寫入數(shù)據(jù)
            excelWriter.write(dataList, writeSheet);

            // 完成寫入
            excelWriter.finish();

            log.info("[ExportTool] 導(dǎo)出成功: {}", fileName);
        } catch (Exception e) {
            log.error("[ExportTool] 導(dǎo)出失敗: {}", fileName, e);
            throw new ServiceException("導(dǎo)出 Excel 失敗");
        }
    }

    /**
     * 設(shè)置 HttpServletResponse 響應(yīng)頭
     */
    private static void setupResponse(HttpServletResponse response, String fileName) throws Exception {
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        String encodedFileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8.toString());
        response.setHeader("Content-Disposition", "attachment;filename=" + encodedFileName);
    }

    /**
     * 創(chuàng)建表頭樣式
     */
    private static WriteCellStyle createHeadStyle() {
        WriteCellStyle headStyle = new WriteCellStyle();

        // 設(shè)置白底(不填充顏色)
        headStyle.setFillForegroundColor(null);
        headStyle.setFillPatternType(FillPatternType.NO_FILL);

        // 設(shè)置字體
        WriteFont headFont = new WriteFont();
        headFont.setFontHeightInPoints((short) 11);
        headFont.setFontName("微軟雅黑");
        headFont.setBold(true);
        headFont.setColor(IndexedColors.PALE_BLUE.getIndex());
        headStyle.setWriteFont(headFont);

        // 設(shè)置居中與自動(dòng)換行
        headStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        headStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        headStyle.setWrapped(true);

        // 設(shè)置無邊框
        headStyle.setBorderLeft(BorderStyle.NONE);
        headStyle.setBorderRight(BorderStyle.NONE);
        headStyle.setBorderTop(BorderStyle.NONE);
        headStyle.setBorderBottom(BorderStyle.NONE);

        return headStyle;
    }

    /**
     * 創(chuàng)建內(nèi)容樣式
     */
    private static WriteCellStyle createContentStyle() {
        WriteCellStyle contentStyle = new WriteCellStyle();

        // 設(shè)置字體
        WriteFont contentFont = new WriteFont();
        contentFont.setFontHeightInPoints((short) 11);
        contentFont.setFontName("等線");
        contentStyle.setWriteFont(contentFont);

        // 內(nèi)容右對(duì)齊,垂直居中,自動(dòng)換行
        contentStyle.setHorizontalAlignment(HorizontalAlignment.RIGHT);
        contentStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        contentStyle.setWrapped(true);

        return contentStyle;
    }

    /**
     * 列寬自適應(yīng)策略(根據(jù)內(nèi)容長度自動(dòng)調(diào)整列寬,限制最小 15、最大 20 字符)
     */
    private static AbstractColumnWidthStyleStrategy createAutoWidthStrategy() {
        return new AbstractColumnWidthStyleStrategy() {
            private final Map<Integer, Integer> columnWidthMap = new HashMap<>();

            @Override
            protected void setColumnWidth(WriteSheetHolder writeSheetHolder,
                                          List<WriteCellData<?>> cellDataList,
                                          Cell cell,
                                          Head head,
                                          Integer relativeRowIndex,
                                          Boolean isHead) {
                if (cell == null || cell.getCellType() != CellType.STRING) return;
                String value = cell.getStringCellValue();
                if (value == null) return;

                Sheet sheet = writeSheetHolder.getSheet();
                int columnIndex = cell.getColumnIndex();

                // 根據(jù) UTF-8 字節(jié)長度計(jì)算列寬
                int length = value.getBytes(StandardCharsets.UTF_8).length;
                int minWidth = 15 * 256;
                int maxWidth = 20 * 256;
                int width = Math.max(minWidth, Math.min(length * 256 + 200, maxWidth));

                // 如果當(dāng)前列寬大于記錄的最大寬度,則更新列寬
                Integer maxWidthRecorded = columnWidthMap.getOrDefault(columnIndex, 0);
                if (width > maxWidthRecorded) {
                    columnWidthMap.put(columnIndex, width);
                    sheet.setColumnWidth(columnIndex, width);
                }

                // 設(shè)置自動(dòng)換行樣式
                CellStyle style = sheet.getWorkbook().createCellStyle();
                style.cloneStyleFrom(cell.getCellStyle());
                style.setWrapText(true);
                cell.setCellStyle(style);
            }
        };
    }

    /**
     * 包裝 Servlet 輸出流,不關(guān)閉底層流
     */
    public static class NoCloseOutputStream extends FilterOutputStream {
        public NoCloseOutputStream(OutputStream out) {
            super(out);
        }

        @Override
        public void close() throws IOException {
            flush(); // 不關(guān)閉底層流,僅刷新
        }
    }
}

3.3 核心方法分析

3.3.1 簡單導(dǎo)出方法

public static <T> void exportExcel(List<T> dataList, Class<T> clazz, String fileName)

功能:快速生成 Excel 文件,無樣式和列寬控制。

執(zhí)行流程

  1. 數(shù)據(jù)判空:日志告警數(shù)據(jù)為空情況。
  2. 獲取響應(yīng)流:通過 WebTool.getResponse() 獲取 HttpServletResponse。
  3. 設(shè)置響應(yīng)頭:設(shè)置 MIME 類型和 Content-Disposition,保證瀏覽器下載文件。
  4. EasyExcel 寫入:調(diào)用 EasyExcel.write(out, clazz).sheet("數(shù)據(jù)").doWrite(dataList),直接寫入數(shù)據(jù)列表。
  5. 異常處理:統(tǒng)一捕獲異常,拋出 ServiceException。

特點(diǎn)

  • 接口簡單,使用泛型可適配任意實(shí)體類
  • 無額外樣式處理,適合數(shù)據(jù)量大或快速導(dǎo)出場景

3.3.2 帶樣式導(dǎo)出方法

public static <T> void exportExcelWithStyle(List<T> dataList, Class<T> clazz, String fileName)

功能:在 Excel 中生成 自定義表頭、內(nèi)容樣式,并自動(dòng)調(diào)整列寬。

執(zhí)行流程

  1. 獲取響應(yīng)流并設(shè)置響應(yīng)頭。
  2. 包裝輸出流:使用 NoCloseOutputStream 防止 EasyExcel 自動(dòng)關(guān)閉底層流。
  3. 構(gòu)建 ExcelWriter
    • 注冊(cè) 表頭樣式 + 內(nèi)容樣式 (HorizontalCellStyleStrategy)
    • 注冊(cè) 列寬自適應(yīng)策略 (AbstractColumnWidthStyleStrategy)
  4. 創(chuàng)建 Sheet:定義名稱,例如 "導(dǎo)出數(shù)據(jù)"。
  5. 寫入數(shù)據(jù)excelWriter.write(dataList, writeSheet)
  6. 完成寫入:調(diào)用 excelWriter.finish() 完成 Excel 寫入流程。
  7. 異常處理:統(tǒng)一日志記錄,拋出 ServiceException

特點(diǎn)

  • 樣式和列寬可獨(dú)立調(diào)整,便于復(fù)用和擴(kuò)展
  • 保證瀏覽器端下載體驗(yàn)不受影響
  • 對(duì)長文本和數(shù)字型列提供自動(dòng)換行和右對(duì)齊

3.4 樣式策略分析

3.4.1 表頭樣式

WriteCellStyle headStyle = createHeadStyle();

特點(diǎn)

  • 字體:微軟雅黑,加粗,顏色淡藍(lán)
  • 對(duì)齊方式:水平居中、垂直居中
  • 自動(dòng)換行,保證多行表頭顯示完整
  • 無邊框、白底,視覺簡潔

設(shè)計(jì)思路

  • 獨(dú)立封裝表頭樣式,便于在多個(gè)導(dǎo)出場景中復(fù)用
  • 樣式可通過 HorizontalCellStyleStrategy 與內(nèi)容樣式統(tǒng)一管理

3.4.2 內(nèi)容樣式

WriteCellStyle contentStyle = createContentStyle();

特點(diǎn)

  • 字體:等線
  • 水平右對(duì)齊(適合數(shù)字、金額)、垂直居中
  • 自動(dòng)換行,保證長文本顯示
  • 與表頭樣式區(qū)分,形成信息層次感

設(shè)計(jì)思路

  • 獨(dú)立封裝內(nèi)容樣式,提高可維護(hù)性
  • 通過策略模式應(yīng)用于 ExcelWriter,無需重復(fù)設(shè)置

3.5 列寬自適應(yīng)策略

AbstractColumnWidthStyleStrategy autoWidthStrategy = createAutoWidthStrategy();

實(shí)現(xiàn)邏輯

  1. 遍歷每個(gè)單元格內(nèi)容,獲取 UTF-8 字節(jié)長度。
  2. 根據(jù)長度計(jì)算列寬,設(shè)置最小 15、最大 20 字符。
  3. 對(duì)比歷史最大列寬,確保列寬不會(huì)縮小。
  4. 設(shè)置單元格自動(dòng)換行,保證內(nèi)容完整顯示。

優(yōu)點(diǎn)

  • 避免手動(dòng)設(shè)置每列寬度
  • 支持中英文混合內(nèi)容,保證可讀性
  • 與樣式策略解耦,可獨(dú)立替換或增強(qiáng)

注意:UTF-8 字節(jié)長度計(jì)算對(duì)不同字符可能略有偏差,中英文混合時(shí)列寬可能需微調(diào)

3.6 輸出流包裝策略

public static class NoCloseOutputStream extends FilterOutputStream

作用

  • EasyExcel 在 finish() 默認(rèn)關(guān)閉流
  • 包裝流后僅執(zhí)行 flush(),不關(guān)閉底層 HttpServletResponse
  • 保證瀏覽器下載文件正常,不中斷響應(yīng)

優(yōu)點(diǎn)

  • 簡單、安全
  • 兼容大多數(shù) Web 導(dǎo)出場景

3.7 ExcelWriter 構(gòu)建與寫入

ExcelWriter excelWriter = EasyExcel.write(noCloseOut, clazz)
        .registerWriteHandler(styleStrategy)
        .registerWriteHandler(autoWidthStrategy)
        .build();

分析

  • 解耦樣式和列寬策略,便于單獨(dú)擴(kuò)展
  • 批量寫入數(shù)據(jù),可適配大數(shù)據(jù)場景
  • 支持自定義 Sheet 名稱
  • 可進(jìn)一步擴(kuò)展:凍結(jié)首行、單元格合并、插入公式等

四、導(dǎo)出對(duì)象類設(shè)計(jì)

@Data
@AllArgsConstructor
@NoArgsConstructor
public class ExportUserVO {

    @ExcelProperty("姓名")
    private String userName;

    @ExcelProperty("ID")
    private Long id;

    @ExcelProperty("使用個(gè)數(shù)")
    private Integer useCount;

}
  • 每個(gè)字段使用 @ExcelProperty 注解列名
  • 數(shù)據(jù)類型支持 String、Integer、Double、Long 等常用類型
  • 對(duì)象類清晰定義列名和數(shù)據(jù)結(jié)構(gòu)

五、示例 Controller 導(dǎo)出方法

@GetMapping("/export")
public void exportUserExcel(HttpServletResponse response) {
    List<ExportUserVO> exportList = Arrays.asList(
        new ExportUserVO("張三", 1001L, 5),
        new ExportUserVO("李四", 1002L, 3)
    );

    String fileName = "用戶導(dǎo)出.xlsx";

    ExportTool.exportExcelWithStyle(response, exportList, ExportUserVO.class, fileName);
}
  • 瀏覽器訪問 /export 即可直接下載 Excel
  • 充分體現(xiàn)工具類的通用性和可復(fù)用性

導(dǎo)出Excel效果

以上就是Java使用EasyExcel導(dǎo)出Excel的全流程詳解的詳細(xì)內(nèi)容,更多關(guān)于Java EasyExcel導(dǎo)出Excel的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • SpringBoot整合MD5加密完成注冊(cè)和登錄方式

    SpringBoot整合MD5加密完成注冊(cè)和登錄方式

    MD5(MessageDigestAlgorithm5)是一種常見的哈希算法,用于生成固定長度(128位)的哈希值,主要應(yīng)用于數(shù)據(jù)完整性校驗(yàn)和密碼存儲(chǔ),MD5具有快速計(jì)算、不可逆性和抗碰撞性等特點(diǎn),盡管存在碰撞漏洞,MD5仍廣泛應(yīng)用于文件下載校驗(yàn)和數(shù)字簽名等場景
    2024-10-10
  • Java 重連機(jī)制的幾種實(shí)現(xiàn)方法

    Java 重連機(jī)制的幾種實(shí)現(xiàn)方法

    本文主要介紹了Java 重連機(jī)制的幾種實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2026-02-02
  • SpringMVC自定義日期轉(zhuǎn)換器方式

    SpringMVC自定義日期轉(zhuǎn)換器方式

    這篇文章主要介紹了SpringMVC如何自定義日期轉(zhuǎn)換器問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-07-07
  • Java開發(fā)異步編程中常用的接口和類示例詳解

    Java開發(fā)異步編程中常用的接口和類示例詳解

    在現(xiàn)代Java中異步編程通常通過不同的機(jī)制和接口來實(shí)現(xiàn),這篇文章主要介紹了Java開發(fā)異步編程中常用的接口和類的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),+需要的朋友可以參考下
    2025-08-08
  • IDEA 程序包不存在,找不到符號(hào)但是明明存在對(duì)應(yīng)的jar包(問題分析及解決方案)

    IDEA 程序包不存在,找不到符號(hào)但是明明存在對(duì)應(yīng)的jar包(問題分析及解決方案)

    這篇文章主要介紹了IDEA 程序包不存在,找不到符號(hào)但是明明存在對(duì)應(yīng)的jar包 的解決方案,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-08-08
  • Java隨機(jī)值設(shè)置(java.util.Random類或Math.random方法)

    Java隨機(jī)值設(shè)置(java.util.Random類或Math.random方法)

    在編程中有時(shí)我們需要生成一些隨機(jī)的字符串作為授權(quán)碼、驗(yàn)證碼等,以確保數(shù)據(jù)的安全性和唯一性,這篇文章主要給大家介紹了關(guān)于Java隨機(jī)值設(shè)置的相關(guān)資料,主要用的是java.util.Random類或Math.random()方法,需要的朋友可以參考下
    2024-08-08
  • MyBatis插件機(jī)制超詳細(xì)講解

    MyBatis插件機(jī)制超詳細(xì)講解

    MyBatis在四大對(duì)象的創(chuàng)建過程中,都會(huì)有插件進(jìn)行介入。插件可以利用動(dòng)態(tài)代理機(jī)制一層層的包裝目標(biāo)對(duì)象,而實(shí)現(xiàn)在目標(biāo)對(duì)象執(zhí)行目標(biāo)方法之前進(jìn)行攔截的效果
    2022-11-11
  • 解決使用this.getClass().getResource()獲取文件時(shí)遇到的坑

    解決使用this.getClass().getResource()獲取文件時(shí)遇到的坑

    這篇文章主要介紹了解決使用this.getClass().getResource()獲取文件時(shí)遇到的坑問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • 詳解Spring中實(shí)現(xiàn)接口動(dòng)態(tài)的解決方法

    詳解Spring中實(shí)現(xiàn)接口動(dòng)態(tài)的解決方法

    最近在工作遇到的一個(gè),發(fā)現(xiàn)網(wǎng)上的資料較少,所以想著總結(jié)分享下,下面這篇文章主要給大家介紹了關(guān)于Spring中實(shí)現(xiàn)接口動(dòng)態(tài)的解決方法,文中通過完整的示例代碼給大家介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-07-07
  • Bloc事件流是一個(gè)阻塞隊(duì)列結(jié)論解析

    Bloc事件流是一個(gè)阻塞隊(duì)列結(jié)論解析

    這篇文章主要為大家介紹了Bloc事件流是一個(gè)阻塞隊(duì)列結(jié)論解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-11-11

最新評(píng)論

高台县| 龙南县| 大名县| 和顺县| 修武县| 桑植县| 灵台县| 枞阳县| 巴塘县| 福海县| 运城市| 教育| 南陵县| 通州市| 翁牛特旗| 西安市| 安多县| 隆子县| 昆明市| 丹江口市| 天等县| 沛县| 库伦旗| 镇康县| 灵川县| 安平县| 安乡县| 汽车| 克什克腾旗| 卢氏县| 张家界市| 高台县| 孟村| 武邑县| 收藏| 山阴县| 梅河口市| 浏阳市| 泗水县| 安丘市| 汕头市|