summaryrefslogtreecommitdiff
path: root/excelize.go
diff options
context:
space:
mode:
authorxuri <xuri.me@gmail.com>2019-07-21 12:56:36 +0800
committerxuri <xuri.me@gmail.com>2019-07-21 12:56:36 +0800
commit35e485756f1d3f5eb1e5f78a5cee06b5ed902645 (patch)
tree32910f1dee6e8970bae8ea1793e03f0a2bcece34 /excelize.go
parent855c3605f6fce4916cdde1dadba2dd73d9f4b744 (diff)
Resolve #217, new function add VBA project supported.
Diffstat (limited to 'excelize.go')
-rw-r--r--excelize.go77
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",
+ })
+ }
+}