package services import ( "bytes" "errors" "eta_gn/eta_api/models" "eta_gn/eta_api/utils" "fmt" "io" "mime/multipart" "os" "os/exec" "strings" "time" "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" ) // 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() { tmpErr := os.Remove(fileName) if tmpErr != nil { utils.FileLog.Info("删除临时存储的svg文件失败, err: " + tmpErr.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() { tmpErr := os.Remove(outFileName) if tmpErr != nil { utils.FileLog.Info("删除生产的图片文件失败, err: " + tmpErr.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 //fontDir := `C:\Users\123\go\src\eta\eta_api\static` 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() }() f2 = &bytes.Buffer{} //strList := []string{waterMarkStr, waterMarkStr, waterMarkStr, waterMarkStr, waterMarkStr, waterMarkStr} strList := []string{waterMarkStr, waterMarkStr, waterMarkStr, waterMarkStr} //strList := []string{waterMarkStr} newWaterMarkStr := strings.Join(strList, " ") wmList := make([]*model.Watermark, 0) for i := types.TopLeft; i <= 9; i++ { wm, tmpErr := api.TextWatermark(newWaterMarkStr, "fo:SimHei, points:48, col: 0.75 0.75 0.75, rot:45, scale:1 abs, opacity:0.3", onTop, update, types.POINTS) if tmpErr != nil { fmt.Println("TextWatermark err:", tmpErr) return } //wm.Pos = types.Center wm.Pos = i 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) }