| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869 |
- package import_service
- import (
- "fmt"
- "path/filepath"
- "strings"
- "github.com/ledongthuc/pdf"
- )
- // PDFParser PDF 解析器(纯 Go,使用 ledongthuc/pdf GetTextByRow 避免竖排)
- type PDFParser struct{}
- // NewPDFParser 创建 PDF 解析器
- func NewPDFParser() *PDFParser {
- return &PDFParser{}
- }
- // Supports 检查是否支持该文件
- func (p *PDFParser) Supports(filePath string) bool {
- return strings.HasSuffix(strings.ToLower(filePath), ".pdf")
- }
- // Parse 解析 PDF 文件(使用 GetTextByRow 按行分组,避免字符竖排)
- func (p *PDFParser) Parse(filePath string) (*ParsedDocument, error) {
- f, reader, err := pdf.Open(filePath)
- if err != nil {
- return nil, fmt.Errorf("打开 PDF 失败: %w", err)
- }
- defer f.Close()
- var allLines []string
- for pageNum := 1; pageNum <= reader.NumPage(); pageNum++ {
- page := reader.Page(pageNum)
- if page.V.IsNull() {
- continue
- }
- rows, err := page.GetTextByRow()
- if err != nil {
- continue
- }
- for _, row := range rows {
- var sb strings.Builder
- for _, t := range row.Content {
- sb.WriteString(t.S)
- }
- line := strings.TrimSpace(sb.String())
- if line != "" {
- allLines = append(allLines, line)
- }
- }
- }
- text := strings.Join(allLines, "\n")
- if strings.TrimSpace(text) == "" {
- return nil, fmt.Errorf("PDF 文件中未提取到文本内容")
- }
- title := strings.TrimSuffix(filepath.Base(filePath), filepath.Ext(filePath))
- return &ParsedDocument{
- Title: title,
- Content: text,
- Metadata: map[string]interface{}{"source": "pdf"},
- }, nil
- }
|