|
|
@@ -0,0 +1,285 @@
|
|
|
+package com.ylx.massage.utils;
|
|
|
+
|
|
|
+import cn.hutool.core.collection.CollUtil;
|
|
|
+import com.ylx.massage.domain.SensitiveWord;
|
|
|
+import org.apache.poi.ss.usermodel.*;
|
|
|
+import org.apache.poi.ss.usermodel.Font;
|
|
|
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
|
|
+import org.slf4j.Logger;
|
|
|
+import org.slf4j.LoggerFactory;
|
|
|
+
|
|
|
+import javax.servlet.http.HttpServletResponse;
|
|
|
+import java.io.IOException;
|
|
|
+import java.io.OutputStream;
|
|
|
+import java.net.URLEncoder;
|
|
|
+import java.text.SimpleDateFormat;
|
|
|
+import java.util.Date;
|
|
|
+import java.util.List;
|
|
|
+
|
|
|
+/**
|
|
|
+ * Excel生成工具类
|
|
|
+ * <p>
|
|
|
+ * 提供生成Excel文件的功能,支持敏感词数据的导出。
|
|
|
+ * 使用Apache POI库创建.xls格式的Excel文件。
|
|
|
+ * </p>
|
|
|
+ *
|
|
|
+ * @author ylx
|
|
|
+ * @version 1.0
|
|
|
+ * @since 2024
|
|
|
+ */
|
|
|
+public class ExcelExportUtils {
|
|
|
+
|
|
|
+ private static final Logger log = LoggerFactory.getLogger(ExcelExportUtils.class);
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 列宽定义
|
|
|
+ */
|
|
|
+ private static final int COLUMN_WIDTH_WORD = 30; // 敏感词列宽
|
|
|
+ private static final int COLUMN_WIDTH_CATEGORY = 20; // 分类列宽
|
|
|
+ private static final int COLUMN_WIDTH_LEVEL = 10; // 等级列宽
|
|
|
+ private static final int COLUMN_WIDTH_STATUS = 10; // 状态列宽
|
|
|
+ private static final int COLUMN_WIDTH_REMARK = 40; // 备注列宽
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 导出敏感词数据到Excel文件
|
|
|
+ * <p>
|
|
|
+ * 将敏感词列表写入Excel工作簿,并输出到HTTP响应流。
|
|
|
+ * Excel文件格式:
|
|
|
+ * - 第一行:表头(敏感词、分类、等级、状态、备注)
|
|
|
+ * - 第二行起:数据行
|
|
|
+ * </p>
|
|
|
+ *
|
|
|
+ * @param wordList 敏感词数据列表
|
|
|
+ * @param response HTTP响应对象
|
|
|
+ * @throws IOException 当写入响应流失败时抛出
|
|
|
+ */
|
|
|
+ public static void exportSensitiveWords(List<SensitiveWord> wordList, HttpServletResponse response) throws IOException {
|
|
|
+ if (CollUtil.isEmpty(wordList)) {
|
|
|
+ log.warn("敏感词数据为空,导出空文件");
|
|
|
+ }
|
|
|
+
|
|
|
+ Workbook workbook = null;
|
|
|
+ OutputStream outputStream = null;
|
|
|
+
|
|
|
+ try {
|
|
|
+ // 1. 创建工作簿(.xls格式)
|
|
|
+ workbook = new HSSFWorkbook();
|
|
|
+
|
|
|
+ // 2. 创建工作表
|
|
|
+ Sheet sheet = workbook.createSheet("敏感词库");
|
|
|
+
|
|
|
+ // 3. 创建表头样式
|
|
|
+ CellStyle headerStyle = createHeaderStyle(workbook);
|
|
|
+
|
|
|
+ // 4. 创建数据样式
|
|
|
+ CellStyle dataStyle = createDataStyle(workbook);
|
|
|
+
|
|
|
+ // 5. 创建表头行
|
|
|
+ Row headerRow = sheet.createRow(0);
|
|
|
+ createHeaderRow(headerRow, headerStyle);
|
|
|
+
|
|
|
+ // 6. 设置列宽
|
|
|
+ setColumnWidths(sheet);
|
|
|
+
|
|
|
+ // 7. 填充数据
|
|
|
+ if (CollUtil.isNotEmpty(wordList)) {
|
|
|
+ int rowNum = 1;
|
|
|
+ for (SensitiveWord word : wordList) {
|
|
|
+ Row dataRow = sheet.createRow(rowNum++);
|
|
|
+ fillDataRow(dataRow, word, dataStyle);
|
|
|
+ }
|
|
|
+ log.info("成功写入 {} 条敏感词数据到Excel", wordList.size());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 8. 生成文件名
|
|
|
+ String fileName = generateFileName();
|
|
|
+
|
|
|
+ // 9. 设置响应头
|
|
|
+ response.setContentType("application/vnd.ms-excel");
|
|
|
+ response.setCharacterEncoding("UTF-8");
|
|
|
+ response.setHeader("Content-Disposition",
|
|
|
+ "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
|
|
|
+
|
|
|
+ // 10. 写入响应流
|
|
|
+ outputStream = response.getOutputStream();
|
|
|
+ workbook.write(outputStream);
|
|
|
+ outputStream.flush();
|
|
|
+
|
|
|
+ log.info("敏感词Excel文件导出成功,文件名:{}", fileName);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("导出敏感词Excel文件失败", e);
|
|
|
+ throw new IOException("导出Excel文件失败:" + e.getMessage());
|
|
|
+ } finally {
|
|
|
+ // 关闭资源
|
|
|
+ if (workbook != null) {
|
|
|
+ try {
|
|
|
+ workbook.close();
|
|
|
+ } catch (IOException e) {
|
|
|
+ log.error("关闭Workbook失败", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (outputStream != null) {
|
|
|
+ try {
|
|
|
+ outputStream.close();
|
|
|
+ } catch (IOException e) {
|
|
|
+ log.error("关闭OutputStream失败", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 创建表头样式
|
|
|
+ * <p>
|
|
|
+ * 表头样式:字体加粗、居中对齐、背景色为浅灰色。
|
|
|
+ * </p>
|
|
|
+ *
|
|
|
+ * @param workbook 工作簿对象
|
|
|
+ * @return 表头样式对象
|
|
|
+ */
|
|
|
+ private static CellStyle createHeaderStyle(Workbook workbook) {
|
|
|
+ CellStyle style = workbook.createCellStyle();
|
|
|
+
|
|
|
+ // 设置字体
|
|
|
+ Font font = workbook.createFont();
|
|
|
+ font.setBold(true);
|
|
|
+ font.setFontHeightInPoints((short) 12);
|
|
|
+ style.setFont(font);
|
|
|
+
|
|
|
+ // 设置对齐方式
|
|
|
+ style.setAlignment(HorizontalAlignment.CENTER);
|
|
|
+ style.setVerticalAlignment(VerticalAlignment.CENTER);
|
|
|
+
|
|
|
+ // 设置背景色
|
|
|
+ style.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
|
|
|
+ style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
|
|
|
+
|
|
|
+ // 设置边框
|
|
|
+ style.setBorderTop(BorderStyle.THIN);
|
|
|
+ style.setBorderBottom(BorderStyle.THIN);
|
|
|
+ style.setBorderLeft(BorderStyle.THIN);
|
|
|
+ style.setBorderRight(BorderStyle.THIN);
|
|
|
+
|
|
|
+ return style;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 创建数据样式
|
|
|
+ * <p>
|
|
|
+ * 数据样式:左对齐、带边框。
|
|
|
+ * </p>
|
|
|
+ *
|
|
|
+ * @param workbook 工作簿对象
|
|
|
+ * @return 数据样式对象
|
|
|
+ */
|
|
|
+ private static CellStyle createDataStyle(Workbook workbook) {
|
|
|
+ CellStyle style = workbook.createCellStyle();
|
|
|
+
|
|
|
+ // 设置字体
|
|
|
+ Font font = workbook.createFont();
|
|
|
+ font.setFontHeightInPoints((short) 11);
|
|
|
+ style.setFont(font);
|
|
|
+
|
|
|
+ // 设置对齐方式
|
|
|
+ style.setAlignment(HorizontalAlignment.LEFT);
|
|
|
+ style.setVerticalAlignment(VerticalAlignment.CENTER);
|
|
|
+
|
|
|
+ // 设置边框
|
|
|
+ style.setBorderTop(BorderStyle.THIN);
|
|
|
+ style.setBorderBottom(BorderStyle.THIN);
|
|
|
+ style.setBorderLeft(BorderStyle.THIN);
|
|
|
+ style.setBorderRight(BorderStyle.THIN);
|
|
|
+
|
|
|
+ // 设置自动换行
|
|
|
+ style.setWrapText(true);
|
|
|
+
|
|
|
+ return style;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 创建表头行
|
|
|
+ * <p>
|
|
|
+ * 在指定行中创建表头单元格。
|
|
|
+ * </p>
|
|
|
+ *
|
|
|
+ * @param row 行对象
|
|
|
+ * @param style 单元格样式
|
|
|
+ */
|
|
|
+ private static void createHeaderRow(Row row, CellStyle style) {
|
|
|
+ String[] headers = {"敏感词", "分类"};
|
|
|
+
|
|
|
+ for (int i = 0; i < headers.length; i++) {
|
|
|
+ Cell cell = row.createCell(i);
|
|
|
+ cell.setCellValue(headers[i]);
|
|
|
+ cell.setCellStyle(style);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 设置列宽
|
|
|
+ * <p>
|
|
|
+ * 为工作表的每一列设置合适的宽度。
|
|
|
+ * </p>
|
|
|
+ *
|
|
|
+ * @param sheet 工作表对象
|
|
|
+ */
|
|
|
+ private static void setColumnWidths(Sheet sheet) {
|
|
|
+ sheet.setColumnWidth(0, COLUMN_WIDTH_WORD * 256); // 敏感词
|
|
|
+ sheet.setColumnWidth(1, COLUMN_WIDTH_CATEGORY * 256); // 分类
|
|
|
+ sheet.setColumnWidth(2, COLUMN_WIDTH_LEVEL * 256); // 等级
|
|
|
+ sheet.setColumnWidth(3, COLUMN_WIDTH_STATUS * 256); // 状态
|
|
|
+ sheet.setColumnWidth(4, COLUMN_WIDTH_REMARK * 256); // 备注
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 填充数据行
|
|
|
+ * <p>
|
|
|
+ * 将敏感词对象的数据写入行中。
|
|
|
+ * </p>
|
|
|
+ *
|
|
|
+ * @param row 行对象
|
|
|
+ * @param word 敏感词对象
|
|
|
+ * @param style 单元格样式
|
|
|
+ */
|
|
|
+ private static void fillDataRow(Row row, SensitiveWord word, CellStyle style) {
|
|
|
+ // 1. 敏感词
|
|
|
+ Cell wordCell = row.createCell(0);
|
|
|
+ wordCell.setCellValue(word.getWord() != null ? word.getWord() : "");
|
|
|
+ wordCell.setCellStyle(style);
|
|
|
+
|
|
|
+ // 2. 分类
|
|
|
+ Cell categoryCell = row.createCell(1);
|
|
|
+ categoryCell.setCellValue(word.getCategory() != null ? word.getCategory() : "");
|
|
|
+ categoryCell.setCellStyle(style);
|
|
|
+
|
|
|
+ // 3. 等级
|
|
|
+ /*Cell levelCell = row.createCell(2);
|
|
|
+ levelCell.setCellValue(word.getLevel() != null ? word.getLevel() : 1);
|
|
|
+ levelCell.setCellStyle(style);*/
|
|
|
+
|
|
|
+ // 4. 状态
|
|
|
+ /*Cell statusCell = row.createCell(3);
|
|
|
+ statusCell.setCellValue(word.getStatus() != null ? word.getStatus() : 1);
|
|
|
+ statusCell.setCellStyle(style);*/
|
|
|
+
|
|
|
+ // 5. 备注
|
|
|
+ /*Cell remarkCell = row.createCell(4);
|
|
|
+ remarkCell.setCellValue(word.getRemark() != null ? word.getRemark() : "");
|
|
|
+ remarkCell.setCellStyle(style);*/
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 生成导出文件名
|
|
|
+ * <p>
|
|
|
+ * 生成格式为:全量敏感词库_当前日期时间.xls
|
|
|
+ * 日期时间格式:yyyyMMddHHmmss
|
|
|
+ * </p>
|
|
|
+ *
|
|
|
+ * @return 文件名字符串
|
|
|
+ */
|
|
|
+ private static String generateFileName() {
|
|
|
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
|
|
|
+ String dateTime = sdf.format(new Date());
|
|
|
+ return "全量敏感词库_" + dateTime + ".xls";
|
|
|
+ }
|
|
|
+}
|