mirror of
https://github.com/gotenberg/gotenberg.git
synced 2026-08-08 00:22:14 +01:00
89 lines
2.0 KiB
Go
89 lines
2.0 KiB
Go
package printer
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"strconv"
|
|
"sync"
|
|
|
|
"github.com/thecodingmachine/gotenberg/internal/pkg/rand"
|
|
)
|
|
|
|
var mu sync.Mutex
|
|
|
|
// Office facilitates Office documents to PDF conversion.
|
|
type Office struct {
|
|
Context context.Context
|
|
FilePaths []string
|
|
PaperWidth float64
|
|
PaperHeight float64
|
|
Landscape bool
|
|
}
|
|
|
|
// Print converts Office documents to PDF.
|
|
func (o *Office) Print(destination string) error {
|
|
mu.Lock()
|
|
defer mu.Unlock()
|
|
fpaths := make([]string, len(o.FilePaths))
|
|
dirPath := filepath.Dir(destination)
|
|
for i, fpath := range o.FilePaths {
|
|
baseFilename, err := rand.Get()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
tmpDest := fmt.Sprintf("%s/%s.pdf", dirPath, baseFilename)
|
|
paperSize, err := unoconvPaperSize(o.PaperWidth, o.PaperHeight)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
cmdArgs := []string{
|
|
"--format",
|
|
"pdf",
|
|
"--printer",
|
|
paperSize,
|
|
}
|
|
if o.Landscape {
|
|
cmdArgs = append(cmdArgs, "--printer", "PaperOrientation=landscape")
|
|
}
|
|
cmdArgs = append(cmdArgs, "--output", tmpDest, fpath)
|
|
cmd := exec.CommandContext(
|
|
o.Context,
|
|
"unoconv",
|
|
cmdArgs...,
|
|
)
|
|
_, err = cmd.Output()
|
|
if o.Context.Err() == context.DeadlineExceeded {
|
|
return errors.New("unoconv: command timed out")
|
|
}
|
|
if err != nil {
|
|
return fmt.Errorf("unoconv: non-zero exit code: %v", err)
|
|
}
|
|
fpaths[i] = tmpDest
|
|
}
|
|
if len(fpaths) == 1 {
|
|
return os.Rename(fpaths[0], destination)
|
|
}
|
|
return Merge(fpaths, destination)
|
|
}
|
|
|
|
func unoconvPaperSize(paperWidth, paperHeight float64) (string, error) {
|
|
width, err := strconv.Atoi(fmt.Sprintf("%.0f", paperWidth*25.4))
|
|
if err != nil {
|
|
return "", fmt.Errorf("%0.f: converting width to millimiter: %v", paperWidth, err)
|
|
}
|
|
height, err := strconv.Atoi(fmt.Sprintf("%.0f", paperHeight*25.4))
|
|
if err != nil {
|
|
return "", fmt.Errorf("%0.f: converting height to millimiter: %v", paperHeight, err)
|
|
}
|
|
return fmt.Sprintf("PaperSize=%dx%d", width, height), nil
|
|
}
|
|
|
|
// Compile-time checks to ensure type implements desired interfaces.
|
|
var (
|
|
_ = Printer(new(Office))
|
|
)
|