diff options
author | xuri <xuri.me@gmail.com> | 2019-07-21 12:56:36 +0800 |
---|---|---|
committer | xuri <xuri.me@gmail.com> | 2019-07-21 12:56:36 +0800 |
commit | 35e485756f1d3f5eb1e5f78a5cee06b5ed902645 (patch) | |
tree | 32910f1dee6e8970bae8ea1793e03f0a2bcece34 /excelize.go | |
parent | 855c3605f6fce4916cdde1dadba2dd73d9f4b744 (diff) |
Resolve #217, new function add VBA project supported.
Diffstat (limited to 'excelize.go')
-rw-r--r-- | excelize.go | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/excelize.go b/excelize.go index f636a84..c7eff10 100644 --- a/excelize.go +++ b/excelize.go @@ -19,7 +19,9 @@ import ( "io" "io/ioutil" "os" + "path" "strconv" + "strings" ) // File define a populated XLSX file struct. @@ -226,3 +228,78 @@ func (f *File) UpdateLinkedValue() error { } return nil } + +// AddVBAProject provides the method to add vbaProject.bin file which contains +// functions and/or macros. The file extension should be .xlsm. For example: +// +// err := f.SetSheetPrOptions("Sheet1", excelize.CodeName("Sheet1")) +// if err != nil { +// fmt.Println(err) +// } +// err = f.AddVBAProject("vbaProject.bin") +// if err != nil { +// fmt.Println(err) +// } +// err = f.SaveAs("macros.xlsm") +// if err != nil { +// fmt.Println(err) +// } +// +func (f *File) AddVBAProject(bin string) error { + var err error + // Check vbaProject.bin exists first. + if _, err = os.Stat(bin); os.IsNotExist(err) { + return err + } + if path.Ext(bin) != ".bin" { + return errors.New("unsupported VBA project extension") + } + f.setContentTypePartVBAProjectExtensions() + wb := f.workbookRelsReader() + var rID int + var ok bool + for _, rel := range wb.Relationships { + if rel.Target == "vbaProject.bin" && rel.Type == SourceRelationshipVBAProject { + ok = true + continue + } + t, _ := strconv.Atoi(strings.TrimPrefix(rel.ID, "rId")) + if t > rID { + rID = t + } + } + rID++ + if !ok { + wb.Relationships = append(wb.Relationships, xlsxWorkbookRelation{ + ID: "rId" + strconv.Itoa(rID), + Target: "vbaProject.bin", + Type: SourceRelationshipVBAProject, + }) + } + file, _ := ioutil.ReadFile(bin) + f.XLSX["xl/vbaProject.bin"] = file + return err +} + +// setContentTypePartVBAProjectExtensions provides a function to set the +// content type for relationship parts and the main document part. +func (f *File) setContentTypePartVBAProjectExtensions() { + var ok bool + content := f.contentTypesReader() + for _, v := range content.Defaults { + if v.Extension == "bin" { + ok = true + } + } + for idx, o := range content.Overrides { + if o.PartName == "/xl/workbook.xml" { + content.Overrides[idx].ContentType = "application/vnd.ms-excel.sheet.macroEnabled.main+xml" + } + } + if !ok { + content.Defaults = append(content.Defaults, xlsxDefault{ + Extension: "bin", + ContentType: "application/vnd.ms-office.vbaProject", + }) + } +} |