Skip to content

Commit e728ff1

Browse files
committed
Fixes qax-os#308, refactor NewSheet(), DeleteSheet(), SetActiveSheet() and GetActiveSheetIndex()
1 parent 62fbc21 commit e728ff1

File tree

6 files changed

+55
-58
lines changed

6 files changed

+55
-58
lines changed

col.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,8 @@ func (f *File) RemoveCol(sheet, column string) {
337337
f.adjustHelper(sheet, col, -1, -1)
338338
}
339339

340-
// completeCol; Completion column element tags of XML in a sheet.
340+
// completeCol provieds function to completion column element tags of XML in a
341+
// sheet.
341342
func completeCol(xlsx *xlsxWorksheet, row, cell int) {
342343
buffer := bytes.Buffer{}
343344
for r := range xlsx.SheetData.Row {

date.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -90,12 +90,13 @@ func julianDateToGregorianTime(part1, part2 float64) time.Time {
9090
return time.Date(year, time.Month(month), day, hours, minutes, seconds, nanoseconds, time.UTC)
9191
}
9292

93-
// doTheFliegelAndVanFlandernAlgorithm; By this point generations of programmers have repeated the algorithm sent
94-
// to the editor of "Communications of the ACM" in 1968 (published in CACM,
95-
// volume 11, number 10, October 1968, p.657). None of those programmers seems
96-
// to have found it necessary to explain the constants or variable names set
97-
// out by Henry F. Fliegel and Thomas C. Van Flandern. Maybe one day I'll buy
98-
// that jounal and expand an explanation here - that day is not today.
93+
// doTheFliegelAndVanFlandernAlgorithm; By this point generations of
94+
// programmers have repeated the algorithm sent to the editor of
95+
// "Communications of the ACM" in 1968 (published in CACM, volume 11, number
96+
// 10, October 1968, p.657). None of those programmers seems to have found it
97+
// necessary to explain the constants or variable names set out by Henry F.
98+
// Fliegel and Thomas C. Van Flandern. Maybe one day I'll buy that jounal and
99+
// expand an explanation here - that day is not today.
99100
func doTheFliegelAndVanFlandernAlgorithm(jd int) (day, month, year int) {
100101
l := jd + 68569
101102
n := (4 * l) / 146097

logo.png

1.83 KB
Loading

sheet.go

Lines changed: 45 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -33,18 +33,27 @@ func (f *File) NewSheet(name string) int {
3333
if f.GetSheetIndex(name) != 0 {
3434
return f.SheetCount
3535
}
36+
f.DeleteSheet(name)
3637
f.SheetCount++
38+
wb := f.workbookReader()
39+
sheetID := 0
40+
for _, v := range wb.Sheets.Sheet {
41+
if v.SheetID > sheetID {
42+
sheetID = v.SheetID
43+
}
44+
}
45+
sheetID++
3746
// Update docProps/app.xml
3847
f.setAppXML()
3948
// Update [Content_Types].xml
40-
f.setContentTypes(f.SheetCount)
49+
f.setContentTypes(sheetID)
4150
// Create new sheet /xl/worksheets/sheet%d.xml
42-
f.setSheet(f.SheetCount, name)
51+
f.setSheet(sheetID, name)
4352
// Update xl/_rels/workbook.xml.rels
44-
rID := f.addXlsxWorkbookRels(f.SheetCount)
53+
rID := f.addXlsxWorkbookRels(sheetID)
4554
// Update xl/workbook.xml
46-
f.setWorkbook(name, rID)
47-
return f.SheetCount
55+
f.setWorkbook(name, sheetID, rID)
56+
return sheetID
4857
}
4958

5059
// contentTypesReader provides a function to get the pointer to the
@@ -118,7 +127,8 @@ func trimCell(column []xlsxC) []xlsxC {
118127
return col[0:i]
119128
}
120129

121-
// setContentTypes; Read and update property of contents type of XLSX.
130+
// setContentTypes provides a function to read and update property of contents
131+
// type of XLSX.
122132
func (f *File) setContentTypes(index int) {
123133
content := f.contentTypesReader()
124134
content.Overrides = append(content.Overrides, xlsxOverride{
@@ -127,7 +137,7 @@ func (f *File) setContentTypes(index int) {
127137
})
128138
}
129139

130-
// setSheet; Update sheet property by given index.
140+
// setSheet provides a function to update sheet property by given index.
131141
func (f *File) setSheet(index int, name string) {
132142
var xlsx xlsxWorksheet
133143
xlsx.Dimension.Ref = "A1"
@@ -141,19 +151,11 @@ func (f *File) setSheet(index int, name string) {
141151

142152
// setWorkbook update workbook property of XLSX. Maximum 31 characters are
143153
// allowed in sheet title.
144-
func (f *File) setWorkbook(name string, rid int) {
154+
func (f *File) setWorkbook(name string, sheetID, rid int) {
145155
content := f.workbookReader()
146-
rID := 0
147-
for _, v := range content.Sheets.Sheet {
148-
t, _ := strconv.Atoi(v.SheetID)
149-
if t > rID {
150-
rID = t
151-
}
152-
}
153-
rID++
154156
content.Sheets.Sheet = append(content.Sheets.Sheet, xlsxSheet{
155157
Name: trimSheetName(name),
156-
SheetID: strconv.Itoa(rID),
158+
SheetID: sheetID,
157159
ID: "rId" + strconv.Itoa(rid),
158160
})
159161
}
@@ -209,13 +211,13 @@ func (f *File) setAppXML() {
209211
f.saveFileList("docProps/app.xml", []byte(templateDocpropsApp))
210212
}
211213

212-
// replaceRelationshipsNameSpaceBytes; Some tools that read XLSX files have very strict requirements about the
213-
// structure of the input XML. In particular both Numbers on the Mac and SAS
214-
// dislike inline XML namespace declarations, or namespace prefixes that don't
215-
// match the ones that Excel itself uses. This is a problem because the Go XML
216-
// library doesn't multiple namespace declarations in a single element of a
217-
// document. This function is a horrible hack to fix that after the XML
218-
// marshalling is completed.
214+
// replaceRelationshipsNameSpaceBytes; Some tools that read XLSX files have
215+
// very strict requirements about the structure of the input XML. In
216+
// particular both Numbers on the Mac and SAS dislike inline XML namespace
217+
// declarations, or namespace prefixes that don't match the ones that Excel
218+
// itself uses. This is a problem because the Go XML library doesn't multiple
219+
// namespace declarations in a single element of a document. This function is
220+
// a horrible hack to fix that after the XML marshalling is completed.
219221
func replaceRelationshipsNameSpaceBytes(workbookMarshal []byte) []byte {
220222
oldXmlns := []byte(`<workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">`)
221223
newXmlns := []byte(`<workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="x15" xmlns:x15="http://schemas.microsoft.com/office/spreadsheetml/2010/11/main">`)
@@ -230,18 +232,23 @@ func (f *File) SetActiveSheet(index int) {
230232
if index < 1 {
231233
index = 1
232234
}
233-
index--
234-
content := f.workbookReader()
235-
if len(content.BookViews.WorkBookView) > 0 {
236-
content.BookViews.WorkBookView[0].ActiveTab = index
237-
} else {
238-
content.BookViews.WorkBookView = append(content.BookViews.WorkBookView, xlsxWorkBookView{
239-
ActiveTab: index,
240-
})
235+
wb := f.workbookReader()
236+
for activeTab, sheet := range wb.Sheets.Sheet {
237+
if sheet.SheetID == index {
238+
if len(wb.BookViews.WorkBookView) > 0 {
239+
wb.BookViews.WorkBookView[0].ActiveTab = activeTab
240+
} else {
241+
wb.BookViews.WorkBookView = append(wb.BookViews.WorkBookView, xlsxWorkBookView{
242+
ActiveTab: activeTab,
243+
})
244+
}
245+
}
241246
}
242-
index++
243247
for idx, name := range f.GetSheetMap() {
244248
xlsx := f.workSheetReader(name)
249+
if len(xlsx.SheetViews.SheetView) > 0 {
250+
xlsx.SheetViews.SheetView[0].TabSelected = false
251+
}
245252
if index == idx {
246253
if len(xlsx.SheetViews.SheetView) > 0 {
247254
xlsx.SheetViews.SheetView[0].TabSelected = true
@@ -250,32 +257,20 @@ func (f *File) SetActiveSheet(index int) {
250257
TabSelected: true,
251258
})
252259
}
253-
} else {
254-
if len(xlsx.SheetViews.SheetView) > 0 {
255-
xlsx.SheetViews.SheetView[0].TabSelected = false
256-
}
257260
}
258261
}
259262
}
260263

261264
// GetActiveSheetIndex provides a function to get active sheet index of the
262265
// XLSX. If not found the active sheet will be return integer 0.
263266
func (f *File) GetActiveSheetIndex() int {
264-
buffer := bytes.Buffer{}
265-
content := f.workbookReader()
266-
for _, v := range content.Sheets.Sheet {
267-
xlsx := xlsxWorksheet{}
268-
buffer.WriteString("xl/worksheets/sheet")
269-
buffer.WriteString(strings.TrimPrefix(v.ID, "rId"))
270-
buffer.WriteString(".xml")
271-
_ = xml.Unmarshal(namespaceStrictToTransitional(f.readXML(buffer.String())), &xlsx)
267+
for idx, name := range f.GetSheetMap() {
268+
xlsx := f.workSheetReader(name)
272269
for _, sheetView := range xlsx.SheetViews.SheetView {
273270
if sheetView.TabSelected {
274-
ID, _ := strconv.Atoi(strings.TrimPrefix(v.ID, "rId"))
275-
return ID
271+
return idx
276272
}
277273
}
278-
buffer.Reset()
279274
}
280275
return 0
281276
}
@@ -404,8 +399,8 @@ func (f *File) DeleteSheet(name string) {
404399
for k, v := range content.Sheets.Sheet {
405400
if v.Name == trimSheetName(name) && len(content.Sheets.Sheet) > 1 {
406401
content.Sheets.Sheet = append(content.Sheets.Sheet[:k], content.Sheets.Sheet[k+1:]...)
407-
sheet := "xl/worksheets/sheet" + strings.TrimPrefix(v.ID, "rId") + ".xml"
408-
rels := "xl/worksheets/_rels/sheet" + strings.TrimPrefix(v.ID, "rId") + ".xml.rels"
402+
sheet := "xl/worksheets/sheet" + strconv.Itoa(v.SheetID) + ".xml"
403+
rels := "xl/worksheets/_rels/sheet" + strconv.Itoa(v.SheetID) + ".xml.rels"
409404
target := f.deleteSheetFromWorkbookRels(v.ID)
410405
f.deleteSheetFromContentTypes(target)
411406
delete(f.sheetMap, name)

test/Book1.xlsx

54 Bytes
Binary file not shown.

xmlWorkbook.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ type xlsxSheets struct {
151151
// not checked it for completeness - it does as much as I need.
152152
type xlsxSheet struct {
153153
Name string `xml:"name,attr,omitempty"`
154-
SheetID string `xml:"sheetId,attr,omitempty"`
154+
SheetID int `xml:"sheetId,attr,omitempty"`
155155
ID string `xml:"http://schemas.openxmlformats.org/officeDocument/2006/relationships id,attr,omitempty"`
156156
State string `xml:"state,attr,omitempty"`
157157
}

0 commit comments

Comments
 (0)