支持对ppt和txt的导入支持
This commit is contained in:
parent
09d2aac37e
commit
33df9bb0f8
@ -10,6 +10,7 @@
|
|||||||
| 1.0.4 | 2025-06-17 | Luke.Ye | 上传文档记录入库 |
|
| 1.0.4 | 2025-06-17 | Luke.Ye | 上传文档记录入库 |
|
||||||
| 1.0.5 | 2025-06-19 | Luke.Ye | 文档导入ES逻辑优化 |
|
| 1.0.5 | 2025-06-19 | Luke.Ye | 文档导入ES逻辑优化 |
|
||||||
| 1.0.6 | 2025-06-20 | Luke.Ye | 完成对象存储删除接口,优化部分代码 |
|
| 1.0.6 | 2025-06-20 | Luke.Ye | 完成对象存储删除接口,优化部分代码 |
|
||||||
|
| 1.1.0 | 2025-06-22 | Luke.Ye | 导入文档类型新增支持ppt & txt |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -7,10 +7,12 @@ package com.knowledge.base.domain.common.enums;
|
|||||||
public enum DocTypeEnum {
|
public enum DocTypeEnum {
|
||||||
|
|
||||||
MARKDOWN("markdown", "markdown"),
|
MARKDOWN("markdown", "markdown"),
|
||||||
HTML("xlsx", "excel"),
|
EXCEL("excel", "excel"),
|
||||||
PDF("pdf", "pdf"),
|
PDF("pdf", "pdf"),
|
||||||
WORD("word", "word"),
|
WORD("word", "word"),
|
||||||
|
|
||||||
|
PPT("ppt", "ppt"),
|
||||||
|
TXT("txt", "txt"),
|
||||||
;
|
;
|
||||||
|
|
||||||
public String code;
|
public String code;
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
package com.knowledge.base.domain.doc.service;
|
package com.knowledge.base.domain.doc.service;
|
||||||
|
|
||||||
import com.knowledge.base.domain.doc.service.impl.AbstractBaseFileImporter;
|
import com.knowledge.base.domain.doc.service.impl.importer.AbstractBaseFileImporter;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
package com.knowledge.base.domain.doc.service.impl;
|
package com.knowledge.base.domain.doc.service.impl.importer;
|
||||||
|
|
||||||
import cn.hutool.core.bean.BeanUtil;
|
import cn.hutool.core.bean.BeanUtil;
|
||||||
import cn.hutool.core.map.MapUtil;
|
import cn.hutool.core.map.MapUtil;
|
||||||
@ -31,7 +31,6 @@ import java.util.*;
|
|||||||
public abstract class AbstractBaseFileImporter implements DocumentImporter {
|
public abstract class AbstractBaseFileImporter implements DocumentImporter {
|
||||||
|
|
||||||
private static final Logger logger = LoggerFactory.getLogger(AbstractBaseFileImporter.class);
|
private static final Logger logger = LoggerFactory.getLogger(AbstractBaseFileImporter.class);
|
||||||
private static final String INDEX_NAME = "documents";
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private FileElasticsearchGateway esGateway;
|
private FileElasticsearchGateway esGateway;
|
||||||
@ -1,6 +1,7 @@
|
|||||||
package com.knowledge.base.domain.doc.service.impl;
|
package com.knowledge.base.domain.doc.service.impl.importer;
|
||||||
|
|
||||||
|
|
||||||
|
import com.knowledge.base.domain.common.enums.DocTypeEnum;
|
||||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||||
import org.apache.poi.ss.usermodel.*;
|
import org.apache.poi.ss.usermodel.*;
|
||||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||||
@ -35,7 +36,7 @@ public class ExcelImporter extends AbstractBaseFileImporter {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String getDocTypeCode() {
|
protected String getDocTypeCode() {
|
||||||
return "excel";
|
return DocTypeEnum.EXCEL.code;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.knowledge.base.domain.doc.service.impl;
|
package com.knowledge.base.domain.doc.service.impl.importer;
|
||||||
|
|
||||||
import com.knowledge.base.domain.common.enums.DocTypeEnum;
|
import com.knowledge.base.domain.common.enums.DocTypeEnum;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.knowledge.base.domain.doc.service.impl;
|
package com.knowledge.base.domain.doc.service.impl.importer;
|
||||||
|
|
||||||
import com.knowledge.base.domain.common.enums.DocTypeEnum;
|
import com.knowledge.base.domain.common.enums.DocTypeEnum;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
@ -0,0 +1,96 @@
|
|||||||
|
package com.knowledge.base.domain.doc.service.impl.importer;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import com.knowledge.base.domain.common.enums.DocTypeEnum;
|
||||||
|
import org.apache.poi.hslf.usermodel.HSLFSlideShow;
|
||||||
|
import org.apache.poi.hslf.usermodel.HSLFSlide;
|
||||||
|
import org.apache.poi.hslf.usermodel.HSLFTextParagraph;
|
||||||
|
import org.apache.poi.xslf.usermodel.XMLSlideShow;
|
||||||
|
import org.apache.poi.xslf.usermodel.XSLFSlide;
|
||||||
|
import org.apache.poi.xslf.usermodel.XSLFTextShape;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PowerPoint 文件导入器,支持 .ppt 和 .pptx 文件。
|
||||||
|
* 利用 Apache POI 提取幻灯片中的所有文本内容。
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class PowerPointImporter extends AbstractBaseFileImporter {
|
||||||
|
|
||||||
|
@Value("${ppt.path}")
|
||||||
|
private String directoryPath;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getDirectoryPath() {
|
||||||
|
return directoryPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<String> getFileSuffixes() {
|
||||||
|
return Set.of(".ppt", ".pptx");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getDocTypeCode() {
|
||||||
|
return DocTypeEnum.PPT.code;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getExcludePrefix() {
|
||||||
|
return directoryPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 提取 PowerPoint 文件中的全部文字内容。
|
||||||
|
*
|
||||||
|
* @param path PPT 文件路径
|
||||||
|
* @return 幻灯片中全部文字拼接而成的字符串
|
||||||
|
* @throws IOException 文件读取异常
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected String extractContent(Path path) throws IOException {
|
||||||
|
String fileName = path.getFileName().toString().toLowerCase();
|
||||||
|
|
||||||
|
try (FileInputStream fis = new FileInputStream(path.toFile())) {
|
||||||
|
if (fileName.endsWith(".pptx")) {
|
||||||
|
XMLSlideShow pptx = new XMLSlideShow(fis);
|
||||||
|
StringBuilder content = new StringBuilder();
|
||||||
|
for (XSLFSlide slide : pptx.getSlides()) {
|
||||||
|
slide.getShapes().stream()
|
||||||
|
.filter(shape -> shape instanceof XSLFTextShape)
|
||||||
|
.map(shape -> (XSLFTextShape) shape)
|
||||||
|
.map(XSLFTextShape::getText)
|
||||||
|
.filter(StrUtil::isNotBlank)
|
||||||
|
.forEach(text -> content.append(text.trim()).append("\n"));
|
||||||
|
}
|
||||||
|
return content.toString();
|
||||||
|
} else if (fileName.endsWith(".ppt")) {
|
||||||
|
HSLFSlideShow ppt = new HSLFSlideShow(fis);
|
||||||
|
StringBuilder content = new StringBuilder();
|
||||||
|
for (HSLFSlide slide : ppt.getSlides()) {
|
||||||
|
List<List<HSLFTextParagraph>> textParagraphs = slide.getTextParagraphs();
|
||||||
|
List<HSLFTextParagraph> paragraphs = textParagraphs.stream()
|
||||||
|
.flatMap(List::stream)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
String slideText = HSLFTextParagraph.getRawText(paragraphs);
|
||||||
|
if (StrUtil.isNotBlank(slideText)) {
|
||||||
|
content.append(slideText.trim()).append("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return content.toString();
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Unsupported PowerPoint format: " + fileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,49 @@
|
|||||||
|
package com.knowledge.base.domain.doc.service.impl.importer;
|
||||||
|
import com.knowledge.base.domain.common.enums.DocTypeEnum;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文本文件导入器,支持 .txt 格式。
|
||||||
|
* 内容按 UTF-8 编码读取,无结构提取,仅用于全文索引。
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class TxtImporter extends AbstractBaseFileImporter {
|
||||||
|
|
||||||
|
@Value("${txt.path}")
|
||||||
|
private String directoryPath;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getDirectoryPath() {
|
||||||
|
return directoryPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<String> getFileSuffixes() {
|
||||||
|
return Set.of(".txt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getDocTypeCode() {
|
||||||
|
return DocTypeEnum.TXT.code;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getExcludePrefix() {
|
||||||
|
return directoryPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String extractContent(Path path) throws IOException {
|
||||||
|
// 读取 UTF-8 编码文本,去除 BOM 和首尾空白
|
||||||
|
String content = Files.readString(path, StandardCharsets.UTF_8);
|
||||||
|
return content.replace("\uFEFF", "").trim();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -1,4 +1,4 @@
|
|||||||
package com.knowledge.base.domain.doc.service.impl;
|
package com.knowledge.base.domain.doc.service.impl.importer;
|
||||||
|
|
||||||
import com.knowledge.base.domain.common.enums.DocTypeEnum;
|
import com.knowledge.base.domain.common.enums.DocTypeEnum;
|
||||||
import org.apache.poi.hwpf.HWPFDocument;
|
import org.apache.poi.hwpf.HWPFDocument;
|
||||||
@ -29,7 +29,7 @@ public class DynamicConfig {
|
|||||||
@Value("${token.expire.time:86400000}")
|
@Value("${token.expire.time:86400000}")
|
||||||
private long tokenExpireTime;
|
private long tokenExpireTime;
|
||||||
|
|
||||||
@Value("${os.supported.searchable.file.suffix: pdf,doc,docx,xls,xlsx}")
|
@Value("${os.supported.searchable.file.suffix: pdf,doc,docx,xls,xlsx,ppt,pptx,txt}")
|
||||||
private String supportedSearchFileSuffix;
|
private String supportedSearchFileSuffix;
|
||||||
|
|
||||||
@Value("${file.import.rate.limit: 10}")
|
@Value("${file.import.rate.limit: 10}")
|
||||||
|
|||||||
@ -40,7 +40,7 @@ public class MinioOSGatewayImpl implements ObjectStorageGateway {
|
|||||||
String localEndPoint = "http://localhost:19000";
|
String localEndPoint = "http://localhost:19000";
|
||||||
if("docker".equals(activeProfile)) {
|
if("docker".equals(activeProfile)) {
|
||||||
localEndPoint = "http://host.docker.internal:19000";
|
localEndPoint = "http://host.docker.internal:19000";
|
||||||
}else if("mac".equals(activeProfile)) {
|
}else if("dev-mac".equals(activeProfile)) {
|
||||||
localEndPoint = "http://s3.wisdompulse.cn";
|
localEndPoint = "http://s3.wisdompulse.cn";
|
||||||
}
|
}
|
||||||
this.localMinioClient = MinioClient.builder()
|
this.localMinioClient = MinioClient.builder()
|
||||||
|
|||||||
@ -27,6 +27,8 @@ markdown.path=/Users/admin/Desktop/Archived/micro-saas
|
|||||||
pdf.path=/Users/admin/Desktop/Archived/micro-saas
|
pdf.path=/Users/admin/Desktop/Archived/micro-saas
|
||||||
word.path=/Users/admin/Desktop/Archived/micro-saas
|
word.path=/Users/admin/Desktop/Archived/micro-saas
|
||||||
excel.path=/Users/admin/Desktop/Archived/micro-saas
|
excel.path=/Users/admin/Desktop/Archived/micro-saas
|
||||||
|
ppt.path=/Users/admin/Desktop/Archived/micro-saas
|
||||||
|
txt.path=/Users/admin/Desktop/Archived/micro-saas
|
||||||
object.storage.local-searchable-path-prefix=/Users/admin/Desktop/Archived/micro-saas
|
object.storage.local-searchable-path-prefix=/Users/admin/Desktop/Archived/micro-saas
|
||||||
|
|
||||||
# mysql
|
# mysql
|
||||||
|
|||||||
@ -31,6 +31,8 @@ markdown.path=D:/02-documents/01-ahnx-share-src-public/public
|
|||||||
pdf.path=D:/02-documents/01-os-uploaded-searchable-files
|
pdf.path=D:/02-documents/01-os-uploaded-searchable-files
|
||||||
word.path=D:/02-documents/01-os-uploaded-searchable-files
|
word.path=D:/02-documents/01-os-uploaded-searchable-files
|
||||||
excel.path=D:/02-documents/01-os-uploaded-searchable-files
|
excel.path=D:/02-documents/01-os-uploaded-searchable-files
|
||||||
|
ppt.path=D:/02-documents/01-os-uploaded-searchable-files
|
||||||
|
txt.path=D:/02-documents/01-os-uploaded-searchable-files
|
||||||
object.storage.local-searchable-path-prefix=D:/02-documents/01-os-uploaded-searchable-files
|
object.storage.local-searchable-path-prefix=D:/02-documents/01-os-uploaded-searchable-files
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -30,6 +30,8 @@ markdown.path=/app/import-data
|
|||||||
pdf.path=/app/os-uploaded-searchable-files
|
pdf.path=/app/os-uploaded-searchable-files
|
||||||
word.path=/app/os-uploaded-searchable-files
|
word.path=/app/os-uploaded-searchable-files
|
||||||
excel.path=/app/os-uploaded-searchable-files
|
excel.path=/app/os-uploaded-searchable-files
|
||||||
|
ppt.path=/app/os-uploaded-searchable-files
|
||||||
|
txt.path=/app/os-uploaded-searchable-files
|
||||||
object.storage.local-searchable-path-prefix=/app/os-uploaded-searchable-files
|
object.storage.local-searchable-path-prefix=/app/os-uploaded-searchable-files
|
||||||
|
|
||||||
# 相对路径裁剪
|
# 相对路径裁剪
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user