From 50820fd9617c6e8e963e07985177182b8fa40acf Mon Sep 17 00:00:00 2001 From: liyf Date: Sun, 5 Apr 2020 09:24:00 +0800 Subject: [PATCH] initial commit --- README.md | 19 +++++- SignOffice.go | 167 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 185 insertions(+), 1 deletion(-) create mode 100644 SignOffice.go diff --git a/README.md b/README.md index ab25e19..a3ae31e 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,20 @@ # SignOffice -Office文件签名程序 \ No newline at end of file +Office文件签名程序 + +支持docx,xlsx签名 + +## 签名方式 +~~~ +SignOffice.exe C:/test.xlsx "签名文字=test;签名图片=pic:C:/test.png" +~~~ + +## word签名设置 +有两种方式: +1. 通过设置属性的方式签名文字 +2. 通过设置在单元格内的书签的方式进行签名,这种方式既可以签名图片,也可以签名文字,放在单元格内也会让图片的大小和单元格一致,**推荐使用这种** + +## excel签名设置 +通过设置单元格的名称即可 + +图片会自动适应单元格大小 \ No newline at end of file diff --git a/SignOffice.go b/SignOffice.go new file mode 100644 index 0000000..30d39e2 --- /dev/null +++ b/SignOffice.go @@ -0,0 +1,167 @@ +package main + +import ( + "os" + "strconv" + "strings" + + "github.com/360EntSecGroup-Skylar/excelize" + "github.com/unidoc/unioffice/common" + "github.com/unidoc/unioffice/document" + "github.com/unidoc/unioffice/measurement" +) + +func main() { + if len(os.Args) > 2 { + file := os.Args[1] + paras := os.Args[2] + split := strings.Split(paras, ";") + paraMap := make(map[string]string) + println("sign:", file) + + for _, str := range split { + index := strings.Index(str, "=") + if index == -1 { + continue + } + paraMap[str[:index]] = str[index+1:] + } + if strings.Contains(file, ".xlsx") { + signExcel(file, paraMap) + } + if strings.Contains(file, ".docx") { + signWord(file, paraMap) + } + } + +} + +func signExcel(file string, paras map[string]string) { + f, err := excelize.OpenFile(file) + if err != nil { + println("open error:", err.Error()) + return + } + names := f.GetDefinedName() + for _, name := range names { + if len(paras[name.Name]) == 0 { + continue + } + sheet, ref := getRealRef(name.RefersTo) + val := paras[name.Name] + index := strings.Index(val, "pic:") + + if index == 0 { + f.DeletePicture(sheet, ref) + val = val[4:] + err = f.AddPicture(sheet, ref, val, `{ "autofit": true}`) + if err != nil { + println("add picture error:", err.Error()) + } + } else { + f.SetCellValue(sheet, ref, val) + } + + } + err = f.Save() + if err != nil { + println("save error:", err.Error()) + } else { + println("success sign:", file) + } +} + +func signWord(file string, paras map[string]string) { + doc, err := document.Open(file) + if err != nil { + println("open error:", err.Error()) + return + } + bookMap, heightMap := doc.BookmarkMap() + for key, value := range bookMap { + if len(paras[key]) == 0 { + continue + } + ps := value.Paragraphs() + for _, p := range ps { + for _, run := range p.Runs() { + p.RemoveRun(run) + } + } + var para document.Paragraph + if len(ps) > 0 { + para = ps[0] + } else { + para = value.AddParagraph() + } + val := paras[key] + index := strings.Index(val, "pic:") + if index == 0 { + val = val[4:] + println("sign picture:", val) + img1, err := common.ImageFromFile(val) + if err != nil { + println("error:", err.Error()) + continue + } + img1ref, err := doc.AddImage(img1) + anc, err := para.AddRun().AddDrawingInline(img1ref) + width := value.Properties().X().TcW.WAttr.String() + for i := 0; i < len(width); i++ { + if width[i] > '9' || width[i] < '0' { + width = width[:i] + break + } + } + w, err := strconv.Atoi(width) + if err != nil { + println("convert error:", err.Error()) + continue + } + anc.SetSize(measurement.Distance(w), measurement.Distance(heightMap[key])*measurement.Twips) + } else { + para.AddRun().AddText(val) + } + } + fieldMap := doc.Fields() + for key, value := range fieldMap { + if len(paras[key]) == 0 { + continue + } + value.X().EG_RunInnerContent[0].T.Content = paras[key] + prop := doc.GetOrCreateCustomProperties().GetPropertyByName(key) + if prop != nil { + if prop.Lpwstr != nil { + *prop.Lpwstr = paras[key] + } + } + } + err = doc.SaveToFile(file) + if err != nil { + println("save error:", err.Error()) + } else { + println("success sign:", file) + } +} + +func getRealRef(ref string) (string, string) { + index := strings.Index(ref, "!") + if index == -1 { + return "", "" + } + sheet := ref[:index] + remains := ref[index+1:] + strs := strings.Split(remains, "$") + ret := "" + if len(strs) > 2 { + ret += strs[1] + index = strings.Index(strs[2], ":") + if index != -1 { + ret += strs[2][:index] + } else { + ret += strs[2] + } + + } + return sheet, ret +}