Golang PDF文件转换问题求助
Golang PDF文件转换问题求助 我需要帮助转换一个PDF文件。转换可以从PDF转为txt,也可以从PDF转为json。这些PDF文件将始终遵循一套固定的文本位置和内容模式。
2 回复
PDF转文本并非易事。尽管存在pdf2txt工具,但它依赖于PDF中嵌入的文本信息。
在最坏的情况下,您可能需要使用OCR软件从像素数据中提取文本。
更多关于Golang PDF文件转换问题求助的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
对于遵循固定模式的PDF文件转换,推荐使用unipdf库进行文本提取和结构化处理。以下是两种转换方式的实现示例:
1. PDF转TXT(提取所有文本)
package main
import (
"fmt"
"os"
"github.com/unidoc/unipdf/v3/extractor"
"github.com/unidoc/unipdf/v3/model"
)
func pdfToTxt(inputPath, outputPath string) error {
f, err := os.Open(inputPath)
if err != nil {
return err
}
defer f.Close()
pdfReader, err := model.NewPdfReader(f)
if err != nil {
return err
}
numPages, err := pdfReader.GetNumPages()
if err != nil {
return err
}
outputFile, err := os.Create(outputPath)
if err != nil {
return err
}
defer outputFile.Close()
for i := 1; i <= numPages; i++ {
page, err := pdfReader.GetPage(i)
if err != nil {
return err
}
ex, err := extractor.New(page)
if err != nil {
return err
}
text, err := ex.ExtractText()
if err != nil {
return err
}
fmt.Fprintf(outputFile, "=== Page %d ===\n%s\n", i, text)
}
return nil
}
func main() {
err := pdfToTxt("input.pdf", "output.txt")
if err != nil {
panic(err)
}
}
2. PDF转JSON(基于固定模式解析)
package main
import (
"encoding/json"
"fmt"
"os"
"regexp"
"strings"
"github.com/unidoc/unipdf/v3/extractor"
"github.com/unidoc/unipdf/v3/model"
)
type DocumentData struct {
Title string `json:"title"`
Author string `json:"author"`
Sections []Section `json:"sections"`
Metadata map[string]string `json:"metadata"`
}
type Section struct {
Header string `json:"header"`
Content string `json:"content"`
}
func pdfToJson(inputPath, outputPath string) error {
f, err := os.Open(inputPath)
if err != nil {
return err
}
defer f.Close()
pdfReader, err := model.NewPdfReader(f)
if err != nil {
return err
}
// 提取所有文本
var fullText strings.Builder
numPages, _ := pdfReader.GetNumPages()
for i := 1; i <= numPages; i++ {
page, err := pdfReader.GetPage(i)
if err != nil {
continue
}
ex, err := extractor.New(page)
if err != nil {
continue
}
text, err := ex.ExtractText()
if err != nil {
continue
}
fullText.WriteString(text + "\n")
}
// 根据固定模式解析文本
docData := parseFixedPattern(fullText.String())
// 转换为JSON
jsonData, err := json.MarshalIndent(docData, "", " ")
if err != nil {
return err
}
return os.WriteFile(outputPath, jsonData, 0644)
}
func parseFixedPattern(text string) DocumentData {
data := DocumentData{
Metadata: make(map[string]string),
}
// 示例:提取标题(假设标题在第一行)
lines := strings.Split(text, "\n")
if len(lines) > 0 {
data.Title = strings.TrimSpace(lines[0])
}
// 示例:使用正则表达式提取特定模式
// 假设作者信息格式为 "Author: 姓名"
authorRe := regexp.MustCompile(`Author:\s*(.+)`)
if matches := authorRe.FindStringSubmatch(text); len(matches) > 1 {
data.Author = matches[1]
}
// 示例:提取章节(假设章节以"## "开头)
sectionRe := regexp.MustCompile(`##\s+(.+?)\n(.+?)(?=##|$)`)
matches := sectionRe.FindAllStringSubmatch(text, -1)
for _, match := range matches {
if len(match) >= 3 {
section := Section{
Header: strings.TrimSpace(match[1]),
Content: strings.TrimSpace(match[2]),
}
data.Sections = append(data.Sections, section)
}
}
// 提取其他元数据(假设格式为"Key: Value")
metaRe := regexp.MustCompile(`(\w+):\s*(.+)`)
allMeta := metaRe.FindAllStringSubmatch(text, -1)
for _, meta := range allMeta {
if len(meta) >= 3 && meta[1] != "Author" {
data.Metadata[meta[1]] = meta[2]
}
}
return data
}
func main() {
err := pdfToJson("input.pdf", "output.json")
if err != nil {
panic(err)
}
}
3. 安装依赖
go get github.com/unidoc/unipdf/v3
4. 针对固定模式的优化建议
如果PDF有严格的固定格式,可以更精确地提取:
func extractByCoordinates(pdfReader *model.PdfReader) map[string]string {
// 使用文本位置信息提取
// 需要根据实际PDF的文本位置调整坐标
result := make(map[string]string)
// 示例:提取特定区域的文本
// 假设标题在 (50, 750) 到 (400, 800) 的矩形区域内
// 实际实现需要使用更精确的文本定位
return result
}
关键点:
unipdf提供了强大的文本提取功能- 对于固定模式的PDF,结合正则表达式可以准确提取结构化数据
- 如果PDF包含表格或复杂布局,可能需要使用
unipdf的TextMark功能获取精确位置信息
根据PDF的具体模式调整正则表达式和解析逻辑即可实现准确的转换。

