186 lines
4.0 KiB
Go
186 lines
4.0 KiB
Go
package services
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
|
|
"github.com/pdfcpu/pdfcpu/pkg/api"
|
|
"github.com/pdfcpu/pdfcpu/pkg/pdfcpu"
|
|
)
|
|
|
|
type PDFService struct{}
|
|
|
|
func NewPDFService() *PDFService {
|
|
return &PDFService{}
|
|
}
|
|
|
|
type PDFInfo struct {
|
|
Pages int `json:"pages"`
|
|
Title string `json:"title"`
|
|
Author string `json:"author"`
|
|
FilePath string `json:"filePath"`
|
|
Size int64 `json:"size"`
|
|
}
|
|
|
|
func (s *PDFService) GetPDFInfo(filePath string) (*PDFInfo, error) {
|
|
info, err := api.Info(filePath, nil)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("获取PDF信息失败: %v", err)
|
|
}
|
|
|
|
fileInfo, err := os.Stat(filePath)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("获取文件信息失败: %v", err)
|
|
}
|
|
|
|
return &PDFInfo{
|
|
Pages: info.Pages,
|
|
Title: info.Title,
|
|
Author: info.Author,
|
|
FilePath: filePath,
|
|
Size: fileInfo.Size(),
|
|
}, nil
|
|
}
|
|
|
|
func (s *PDFService) CompressPDF(inputPath, outputPath string, quality string) error {
|
|
if outputPath == "" {
|
|
outputPath = getOutputPath(inputPath, "_compressed")
|
|
}
|
|
|
|
inFile, err := os.Open(inputPath)
|
|
if err != nil {
|
|
return fmt.Errorf("打开输入文件失败: %v", err)
|
|
}
|
|
defer inFile.Close()
|
|
|
|
outFile, err := os.Create(outputPath)
|
|
if err != nil {
|
|
return fmt.Errorf("创建输出文件失败: %v", err)
|
|
}
|
|
defer outFile.Close()
|
|
|
|
conf := pdfcpu.NewDefaultConfiguration()
|
|
|
|
switch quality {
|
|
case "high":
|
|
conf.Quality = 0.9
|
|
case "medium":
|
|
conf.Quality = 0.7
|
|
case "low":
|
|
conf.Quality = 0.5
|
|
default:
|
|
conf.Quality = 0.7
|
|
}
|
|
|
|
err = api.Optimize(inFile, outFile, conf)
|
|
if err != nil {
|
|
return fmt.Errorf("压缩PDF失败: %v", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (s *PDFService) SplitPDF(inputPath, outputDir string, pages string) ([]string, error) {
|
|
if outputDir == "" {
|
|
outputDir = filepath.Dir(inputPath)
|
|
}
|
|
|
|
outFiles, err := api.Split(inputPath, outputDir, pages, false, nil)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("分割PDF失败: %v", err)
|
|
}
|
|
|
|
return outFiles, nil
|
|
}
|
|
|
|
func (s *PDFService) MergePDFs(inputPaths []string, outputPath string) error {
|
|
if outputPath == "" {
|
|
outputPath = filepath.Join(filepath.Dir(inputPaths[0]), "merged.pdf")
|
|
}
|
|
|
|
outFile, err := os.Create(outputPath)
|
|
if err != nil {
|
|
return fmt.Errorf("创建输出文件失败: %v", err)
|
|
}
|
|
defer outFile.Close()
|
|
|
|
var inFiles []*os.File
|
|
for _, p := range inputPaths {
|
|
f, err := os.Open(p)
|
|
if err != nil {
|
|
return fmt.Errorf("打开文件失败 %s: %v", p, err)
|
|
}
|
|
defer f.Close()
|
|
inFiles = append(inFiles, f)
|
|
}
|
|
|
|
conf := pdfcpu.NewDefaultConfiguration()
|
|
err = api.Merge(inFiles, outFile, conf)
|
|
if err != nil {
|
|
return fmt.Errorf("合并PDF失败: %v", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (s *PDFService) RotatePDF(inputPath, outputPath string, rotation int) error {
|
|
if outputPath == "" {
|
|
outputPath = getOutputPath(inputPath, "_rotated")
|
|
}
|
|
|
|
inFile, err := os.Open(inputPath)
|
|
if err != nil {
|
|
return fmt.Errorf("打开输入文件失败: %v", err)
|
|
}
|
|
defer inFile.Close()
|
|
|
|
outFile, err := os.Create(outputPath)
|
|
if err != nil {
|
|
return fmt.Errorf("创建输出文件失败: %v", err)
|
|
}
|
|
defer outFile.Close()
|
|
|
|
conf := pdfcpu.NewDefaultConfiguration()
|
|
pages := "1-" // All pages
|
|
|
|
err = api.Rotate(inFile, outFile, pages, rotation, conf)
|
|
if err != nil {
|
|
return fmt.Errorf("旋转PDF失败: %v", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (s *PDFService) AddWatermark(inputPath, outputPath, text string) error {
|
|
if outputPath == "" {
|
|
outputPath = getOutputPath(inputPath, "_watermarked")
|
|
}
|
|
|
|
inFile, err := os.Open(inputPath)
|
|
if err != nil {
|
|
return fmt.Errorf("打开输入文件失败: %v", err)
|
|
}
|
|
defer inFile.Close()
|
|
|
|
outFile, err := os.Create(outputPath)
|
|
if err != nil {
|
|
return fmt.Errorf("创建输出文件失败: %v", err)
|
|
}
|
|
defer outFile.Close()
|
|
|
|
conf := pdfcpu.NewDefaultConfiguration()
|
|
|
|
wm, err := pdfcpu.TextWatermark(text, "20pt", true, 0.3, 0)
|
|
if err != nil {
|
|
return fmt.Errorf("创建水印失败: %v", err)
|
|
}
|
|
|
|
err = api.AddWatermarks(inFile, outFile, nil, wm, conf)
|
|
if err != nil {
|
|
return fmt.Errorf("添加水印失败: %v", err)
|
|
}
|
|
|
|
return nil
|
|
}
|