123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327 |
- package services
- import (
- "bytes"
- "errors"
- "eta/eta_api/models"
- "eta/eta_api/utils"
- "fmt"
- "github.com/pdfcpu/pdfcpu/pkg/api"
- "github.com/pdfcpu/pdfcpu/pkg/font"
- "github.com/pdfcpu/pdfcpu/pkg/pdfcpu"
- "github.com/pdfcpu/pdfcpu/pkg/pdfcpu/model"
- "github.com/pdfcpu/pdfcpu/pkg/pdfcpu/types"
- "io"
- "mime/multipart"
- "os"
- "os/exec"
- "strings"
- "time"
- )
- // UploadToOssAndFileName 上传到oss并使用这个名称
- func UploadToOssAndFileName(fileMulti multipart.File, newFileName string) (resourceUrl string, err error) {
- dateDir := time.Now().Format("20060102")
- uploadDir := utils.STATIC_DIR + "hongze/" + dateDir
- err = os.MkdirAll(uploadDir, utils.DIR_MOD)
- if err != nil {
- err = errors.New("存储目录创建失败,Err:" + err.Error())
- return
- }
- //本地地址
- fpath := uploadDir + "/" + newFileName
- err = saveToFile(fileMulti, fpath)
- if err != nil {
- err = errors.New("文件上传失败,Err:" + err.Error())
- return
- }
- //上传到阿里云 和 minio
- //if utils.ObjectStorageClient == "minio" {
- // resourceUrl, err = UploadImgToMinIo(newFileName, fpath)
- // if err != nil {
- // err = errors.New("文件上传失败,Err:" + err.Error())
- // return
- // }
- //} else {
- // resourceUrl, err = UploadAliyunV2(newFileName, fpath)
- // if err != nil {
- // err = errors.New("文件上传失败,Err:" + err.Error())
- // return
- // }
- //}
- ossClient := NewOssClient()
- if ossClient == nil {
- err = fmt.Errorf("初始化OSS服务失败")
- return
- }
- resourceUrl, err = ossClient.UploadFile(newFileName, fpath, "")
- if err != nil {
- err = fmt.Errorf("文件上传失败, Err: %s", err.Error())
- return
- }
- defer func() {
- os.Remove(fpath)
- }()
- item := new(models.Resource)
- item.ResourceUrl = resourceUrl
- item.ResourceType = 1
- item.CreateTime = time.Now()
- _, err = models.AddResource(item)
- if err != nil {
- err = errors.New("资源上传失败,Err:" + err.Error())
- return
- }
- return
- }
- // saveToFile 保存到本地文件
- func saveToFile(fileMulti multipart.File, tofile string) error {
- f, err := os.OpenFile(tofile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0666)
- if err != nil {
- return err
- }
- defer f.Close()
- io.Copy(f, fileMulti)
- return nil
- }
- // GetResourceUrlBySvgImg
- // @Description: 通过svg图片生成图片资源地址(传到OSS后的地址)
- // @author: Roc
- // @datetime 2024-07-16 10:18:09
- // @param imgData string
- // @return resourceUrl string
- // @return err error
- // @return errMsg string
- func GetResourceUrlBySvgImg(imgData string) (resourceUrl string, err error, errMsg string) {
- errMsg = "图表保存失败"
- uploadDir := "static/images/"
- if !utils.FileIsExist(uploadDir) {
- err = os.MkdirAll(uploadDir, utils.DIR_MOD)
- if err != nil {
- err = errors.New("存储目录创建失败,Err:" + err.Error())
- return
- }
- }
- //var saveToOssPath string
- randStr := utils.GetRandStringNoSpecialChar(28)
- var fileName, outFileName string
- fileName = randStr + ".txt"
- fileName = uploadDir + fileName
- err = utils.SaveToFile(imgData, fileName)
- if err != nil {
- err = errors.New("图片保存失败,Err:" + err.Error())
- return
- }
- // 删除临时存储的svg文件
- defer func() {
- err = os.Remove(fileName)
- if err != nil {
- utils.FileLog.Info("删除临时存储的svg文件失败, err: " + err.Error())
- }
- }()
- outFileName = randStr + ".png"
- doneChannel := make(chan bool, 1)
- errorChannel := make(chan error, 1)
- cmd := exec.Command("highcharts-export-server", "--infile", fileName, "--constr", "Chart", "--scale", "2", "--workers", "10", "--workLimit", "3", "--outfile", outFileName)
- go func() {
- output, err := cmd.CombinedOutput()
- if err != nil {
- utils.FileLog.Info("execute command failed, output: , error: \n" + string(output) + err.Error())
- errorChannel <- err
- return
- }
- doneChannel <- true
- }()
- defer func() {
- _ = os.Remove(outFileName)
- if err != nil {
- utils.FileLog.Info("删除生产的图片文件失败, err: " + err.Error())
- }
- }()
- select {
- case <-time.After(30 * time.Second):
- utils.FileLog.Info("执行超过30秒 杀死超时进程")
- e := cmd.Process.Kill()
- if e != nil {
- fmt.Println("cmd kill err: ", e.Error())
- utils.FileLog.Info(fmt.Sprintf("cmd kill err: %s", e.Error()))
- errMsg = "图片生成失败"
- err = errors.New("图片生成失败, 执行超时" + e.Error())
- return
- }
- fmt.Println("timeout kill process")
- case <-doneChannel:
- fmt.Println("done")
- case e := <-errorChannel:
- errMsg = "文件上传失败"
- err = errors.New(fmt.Sprintf("execute command failure err: %s", e.Error()))
- fmt.Println("execute command failure err:" + e.Error())
- return
- }
- //上传到阿里云 和 minio
- ossClient := NewOssClient()
- if ossClient == nil {
- errMsg = "上传失败"
- err = errors.New("初始化OSS服务失败")
- return
- }
- resourceUrl, err = ossClient.UploadFile(outFileName, outFileName, "")
- if err != nil {
- errMsg = "文件上传失败"
- err = errors.New("文件上传失败,Err:" + err.Error())
- return
- }
- return
- }
- func GeneralWaterMarkPdf(pdfPath, waterMarkStr string) (f2 *bytes.Buffer, err error) {
- onTop := true
- update := false
- desc := "fo:SimHei, points:38, rot:30, col: 0.75 0.75 0.75, scale:1 abs, opacity:0.3"
- fontDir := `static`
- font.UserFontDir = fontDir
- ttfList := fontDir + `/SimHei.ttf`
- err = api.InstallFonts([]string{ttfList})
- if err != nil {
- fmt.Println("InstallFonts err:", err)
- }
- api.DisableConfigDir()
- f1, err := os.Open(pdfPath)
- if err != nil {
- fmt.Println("文件不存在")
- return
- }
- defer func() {
- _ = f1.Close()
- }()
- fmt.Println(len(waterMarkStr))
- f2 = &bytes.Buffer{}
- wm, tmpErr := api.TextWatermark(waterMarkStr, desc, onTop, update, types.POINTS)
- if tmpErr != nil {
- fmt.Println("TextWatermark err:", tmpErr)
- return
- }
- wm.Pos = types.TopCenter
- realFontSize := wm.ScaledFontSize
- if realFontSize <= 0 {
- realFontSize = wm.FontSize
- }
- targetLineWidth := font.TextWidth(waterMarkStr, wm.FontName, realFontSize)
- targetText := waterMarkStr
- var ctxCpu *model.Context
- ctxCpu, err = api.ReadValidateAndOptimize(f1, api.LoadConfiguration())
- if err != nil {
- return nil, err
- }
- var dms []types.Dim
- dms, err = ctxCpu.PageDims()
- if err != nil {
- return nil, err
- }
- dm := dms[0]
- fmt.Println("targetLineWidth", targetLineWidth)
- if targetLineWidth*2 > dm.Width {
- targetText += " "
- for _, v := range waterMarkStr {
- if dm.Width <= targetLineWidth {
- break
- }
- targetText += fmt.Sprintf("%c", v)
- targetLineWidth = font.TextWidth(targetText, wm.FontName, realFontSize)
- }
- } else {
- for dm.Width >= targetLineWidth {
- targetText += " " + waterMarkStr
- targetLineWidth = font.TextWidth(targetText, wm.FontName, realFontSize)
- }
- }
- fmt.Println("dm.Width", dm.Width, " dm.Height", dm.Height)
- var sb2 strings.Builder
- lineSpace := "\n \n \n"
- rows := 8
- targetText1 := ""
- targetLength := len(targetText)
- for _, v := range targetText {
- if targetLength-len(targetText1) < 8 {
- break
- }
- targetText1 += fmt.Sprintf("%c", v)
- }
- //fmt.Println(targetText1)
- for i := 0; i < rows; i++ {
- if i%2 == 0 {
- sb2.WriteString(targetText)
- } else {
- sb2.WriteString(strings.Repeat(" ", 8))
- sb2.WriteString(targetText1)
- }
- if i < rows-1 {
- sb2.WriteString(lineSpace)
- }
- }
- //fmt.Println(sb2.String())
- wmList := make([]*model.Watermark, 0)
- wm, tmpErr = api.TextWatermark(sb2.String(), desc, onTop, update, types.POINTS)
- if tmpErr != nil {
- fmt.Println("TextWatermark err:", tmpErr)
- return
- }
- wm.Pos = types.TopCenter
- wmList = append(wmList, wm)
- err = AddWatermarks(f1, f2, nil, wmList, nil)
- return
- }
- func AddWatermarks(rs io.ReadSeeker, w io.Writer, selectedPages []string, wmList []*model.Watermark, conf *model.Configuration) error {
- if rs == nil {
- return errors.New("pdfcpu: AddWatermarks: missing rs")
- }
- if conf == nil {
- conf = model.NewDefaultConfiguration()
- }
- conf.Cmd = model.ADDWATERMARKS
- conf.OptimizeDuplicateContentStreams = false
- if len(wmList) <= 0 {
- return errors.New("pdfcpu: missing watermark configuration")
- }
- ctx, err := api.ReadValidateAndOptimize(rs, conf)
- if err != nil {
- return err
- }
- var pages types.IntSet
- pages, err = api.PagesForPageSelection(ctx.PageCount, selectedPages, true, true)
- if err != nil {
- return err
- }
- for _, wm := range wmList {
- if err = pdfcpu.AddWatermarks(ctx, pages, wm); err != nil {
- return err
- }
- }
- return api.Write(ctx, w, conf)
- }
|