Java Apache POI 操作 Excel 導(dǎo)出

Java 可以通過(guò) Apache POI 操作 Excel 的導(dǎo)入導(dǎo)出
Apache POI 是一套操作 Microsoft Office 套件的開(kāi)源 Java API

更多精彩

JAR 包依賴及介紹

  1. 請(qǐng)參見(jiàn) Java Apache POI 操作 Excel 導(dǎo)入

實(shí)現(xiàn)步驟

創(chuàng)建 Excel 實(shí)體類(lèi),用于同一接收導(dǎo)出數(shù)據(jù)

  1. headers 用于存儲(chǔ)導(dǎo)出數(shù)據(jù)時(shí)規(guī)定的表格頭部?jī)?nèi)容
  2. cells 是一個(gè)在 List 中嵌套 List 的結(jié)構(gòu)
    • 外層的 List 表示行數(shù)據(jù)
    • 內(nèi)層的 List 表示列數(shù)據(jù)
    • 結(jié)合起來(lái)也就是有多少行多少列的數(shù)據(jù)
  3. 如果導(dǎo)出的內(nèi)容存在多個(gè) sheet ,只需要使用一個(gè) Map ,通過(guò) key-value 的形式包裝 Excel 實(shí)體類(lèi)即可
    • 例如 Map<String, Excel> excels ,Map 中的 key 就是 sheet 的名稱
public class Excel {
    // 表頭
    private List<String> headers = Lists.newArrayList();

    // 內(nèi)容
    private List<List<String>> cells = Lists.newArrayList();

    // 省略 Getter/Setter 方法
}

舉一個(gè)上述實(shí)體類(lèi)使用的例子

  1. 傳入的數(shù)據(jù)本身就很復(fù)雜,需要導(dǎo)出的數(shù)據(jù)也存在多個(gè) sheet
private Map<String, Excel> wrapFeedbackQuestions(Map<String, ArrayList<FeedbackQuestion>> feedbackQuestionMap) {
    Map<String, Excel> excels = Maps.newHashMap();

    if (feedbackQuestionMap.isEmpty()) {
        throw new TSharkException("統(tǒng)計(jì)數(shù)據(jù)轉(zhuǎn)換異常,請(qǐng)咨詢管理員");
    }

    List<String> divide = Lists.newArrayList();

    feedbackQuestionMap.forEach((k, v) -> {
        Excel excel = new Excel();
        excel.addHeader("題目");
        excel.addHeader("小計(jì)");

        v.forEach(feedbackQuestion -> {
            // 按照約定格式每行添加數(shù)據(jù)
            List<String> row = Lists.newArrayList();
            row.add(feedbackQuestion.getContent());
            row.add(feedbackQuestion.getCount().toString());

            excel.addCell(row);
        });

        excels.put(k, excel);
    });

    return excels;
}

構(gòu)建 ExcelExportUtil 工具類(lèi)

  1. Map<String, Excel> excel 是通過(guò)上述操作構(gòu)建好的數(shù)據(jù)結(jié)構(gòu)
  2. String filePath 是生成 Excel 后,存放文件的地址
  3. initHeaderStyle()initCellStyle() 是對(duì)表格樣式的初始化,在后續(xù)步驟中提供
  4. formatLongValue() 是為了防止單元格內(nèi)容過(guò)長(zhǎng),而設(shè)置的超過(guò)一定量長(zhǎng)度添加換行符
public static String export(Map<String, Excel> excel, String filePath) {
    HSSFWorkbook workbook = new HSSFWorkbook();

    // 表頭樣式
    HSSFCellStyle headerStyle = initHeaderStyle(workbook);

    // 單元格樣式
    HSSFCellStyle cellStyle = initCellStyle(workbook);

    excel.forEach((key, value) -> {
        HSSFSheet sheet = workbook.createSheet(key);

        List<String> headers = value.getHeaders();
        List<List<String>> cells = value.getCells();

        // 表頭包裝
        HSSFRow headerRow = sheet.createRow(0);
        for (int i = 0; i < headers.size(); i++) {
            HSSFCell cell = headerRow.createCell(i);
            cell.setCellValue(headers.get(i));
            cell.setCellStyle(headerStyle);
        }

        // 內(nèi)容包裝
        for (int j = 0; j < cells.size(); j++) {
            HSSFRow row = sheet.createRow(j + 1);

            List<String> child = cells.get(j);
            for (int k = 0; k < child.size(); k++) {
                HSSFCell cell = row.createCell(k);
                cell.setCellValue(formatLongValue(child.get(k)));
                cell.setCellStyle(cellStyle);
            }
        }

        // 自動(dòng)撐開(kāi)列寬
        sheet.autoSizeColumn((short) 0);
        sheet.autoSizeColumn((short) 1);
    });

    // 保存文件并返回名稱
    String fileName = FileUtil.getRandomFileNameByDate();

    try {
        String fullFileName = filePath + fileName + FILE_SUFFIX;

        FileOutputStream stream = new FileOutputStream(fullFileName);
        workbook.write(stream);
        stream.flush();
    } catch (Exception e) {
        logger.error("Excel導(dǎo)出失敗,", e);
    }

    return fileName;
}

initHeaderStyle() 初始化表頭樣式

  1. 對(duì)表頭單元格的字體、顏色、背景做一些自定義操作
private static HSSFCellStyle initHeaderStyle(HSSFWorkbook workbook) {
    // 表頭字體
    HSSFFont font = workbook.createFont();
    font.setFontHeightInPoints((short) 15);
    font.setColor(HSSFColor.WHITE.index);

    // 表頭樣式
    HSSFCellStyle headerStyle = workbook.createCellStyle();
    headerStyle.setFont(font);
    headerStyle.setWrapText(true);
    headerStyle.setFillBackgroundColor(HSSFColor.GREEN.index);
    headerStyle.setFillForegroundColor(HSSFColor.GREEN.index);
    // 需要設(shè)置此項(xiàng),單元格背景色才會(huì)生效
    headerStyle.setFillPattern(CellStyle.SOLID_FOREGROUND);

    return headerStyle;
}

initCellStyle 初始化單元格樣式

private static HSSFCellStyle initCellStyle(HSSFWorkbook workbook) {
    // 單元格字體
    HSSFFont font = workbook.createFont();
    font.setFontHeightInPoints((short) 15);

    // 單元格樣式
    HSSFCellStyle cellStyle = workbook.createCellStyle();
    cellStyle.setFont(font);
    cellStyle.setWrapText(true);

    return cellStyle;
}

formatLongValue 格式化超長(zhǎng)內(nèi)容

  1. 需要單元格啟用 setWrapText = true 才會(huì)生效
private static String formatLongValue(String value) {
    // 長(zhǎng)度限制
    int limit = 50;

    // 沒(méi)有達(dá)到限制直接返回
    if (value.length() < 50) {
        return value;
    }

    StringBuilder stringBuilder = new StringBuilder();

    // 設(shè)置長(zhǎng)度限制的正則匹配
    Pattern p = Pattern.compile("(.{" + limit + "}|.*)");
    Matcher m = p.matcher(value);

    while (m.find()) {
        String group = m.group();

        // 字符不存在則跳過(guò)
        if (group == null || group.trim().equals("")) {
            continue;
        }

        // 超過(guò)限制添加換行符
        stringBuilder.append(group);
        stringBuilder.append("\n");
    }

    return stringBuilder.toString();
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容