forked from p30928647/excelize
Fixes #308, refactor `NewSheet()`, `DeleteSheet()`, `SetActiveSheet()` and `GetActiveSheetIndex()`
This commit is contained in:
parent
62fbc216a7
commit
e728ff1498
3
col.go
3
col.go
|
@ -337,7 +337,8 @@ func (f *File) RemoveCol(sheet, column string) {
|
|||
f.adjustHelper(sheet, col, -1, -1)
|
||||
}
|
||||
|
||||
// completeCol; Completion column element tags of XML in a sheet.
|
||||
// completeCol provieds function to completion column element tags of XML in a
|
||||
// sheet.
|
||||
func completeCol(xlsx *xlsxWorksheet, row, cell int) {
|
||||
buffer := bytes.Buffer{}
|
||||
for r := range xlsx.SheetData.Row {
|
||||
|
|
13
date.go
13
date.go
|
@ -90,12 +90,13 @@ func julianDateToGregorianTime(part1, part2 float64) time.Time {
|
|||
return time.Date(year, time.Month(month), day, hours, minutes, seconds, nanoseconds, time.UTC)
|
||||
}
|
||||
|
||||
// doTheFliegelAndVanFlandernAlgorithm; By this point generations of programmers have repeated the algorithm sent
|
||||
// to the editor of "Communications of the ACM" in 1968 (published in CACM,
|
||||
// volume 11, number 10, October 1968, p.657). None of those programmers seems
|
||||
// to have found it necessary to explain the constants or variable names set
|
||||
// out by Henry F. Fliegel and Thomas C. Van Flandern. Maybe one day I'll buy
|
||||
// that jounal and expand an explanation here - that day is not today.
|
||||
// doTheFliegelAndVanFlandernAlgorithm; By this point generations of
|
||||
// programmers have repeated the algorithm sent to the editor of
|
||||
// "Communications of the ACM" in 1968 (published in CACM, volume 11, number
|
||||
// 10, October 1968, p.657). None of those programmers seems to have found it
|
||||
// necessary to explain the constants or variable names set out by Henry F.
|
||||
// Fliegel and Thomas C. Van Flandern. Maybe one day I'll buy that jounal and
|
||||
// expand an explanation here - that day is not today.
|
||||
func doTheFliegelAndVanFlandernAlgorithm(jd int) (day, month, year int) {
|
||||
l := jd + 68569
|
||||
n := (4 * l) / 146097
|
||||
|
|
BIN
logo.png
BIN
logo.png
Binary file not shown.
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 6.9 KiB |
95
sheet.go
95
sheet.go
|
@ -33,18 +33,27 @@ func (f *File) NewSheet(name string) int {
|
|||
if f.GetSheetIndex(name) != 0 {
|
||||
return f.SheetCount
|
||||
}
|
||||
f.DeleteSheet(name)
|
||||
f.SheetCount++
|
||||
wb := f.workbookReader()
|
||||
sheetID := 0
|
||||
for _, v := range wb.Sheets.Sheet {
|
||||
if v.SheetID > sheetID {
|
||||
sheetID = v.SheetID
|
||||
}
|
||||
}
|
||||
sheetID++
|
||||
// Update docProps/app.xml
|
||||
f.setAppXML()
|
||||
// Update [Content_Types].xml
|
||||
f.setContentTypes(f.SheetCount)
|
||||
f.setContentTypes(sheetID)
|
||||
// Create new sheet /xl/worksheets/sheet%d.xml
|
||||
f.setSheet(f.SheetCount, name)
|
||||
f.setSheet(sheetID, name)
|
||||
// Update xl/_rels/workbook.xml.rels
|
||||
rID := f.addXlsxWorkbookRels(f.SheetCount)
|
||||
rID := f.addXlsxWorkbookRels(sheetID)
|
||||
// Update xl/workbook.xml
|
||||
f.setWorkbook(name, rID)
|
||||
return f.SheetCount
|
||||
f.setWorkbook(name, sheetID, rID)
|
||||
return sheetID
|
||||
}
|
||||
|
||||
// contentTypesReader provides a function to get the pointer to the
|
||||
|
@ -118,7 +127,8 @@ func trimCell(column []xlsxC) []xlsxC {
|
|||
return col[0:i]
|
||||
}
|
||||
|
||||
// setContentTypes; Read and update property of contents type of XLSX.
|
||||
// setContentTypes provides a function to read and update property of contents
|
||||
// type of XLSX.
|
||||
func (f *File) setContentTypes(index int) {
|
||||
content := f.contentTypesReader()
|
||||
content.Overrides = append(content.Overrides, xlsxOverride{
|
||||
|
@ -127,7 +137,7 @@ func (f *File) setContentTypes(index int) {
|
|||
})
|
||||
}
|
||||
|
||||
// setSheet; Update sheet property by given index.
|
||||
// setSheet provides a function to update sheet property by given index.
|
||||
func (f *File) setSheet(index int, name string) {
|
||||
var xlsx xlsxWorksheet
|
||||
xlsx.Dimension.Ref = "A1"
|
||||
|
@ -141,19 +151,11 @@ func (f *File) setSheet(index int, name string) {
|
|||
|
||||
// setWorkbook update workbook property of XLSX. Maximum 31 characters are
|
||||
// allowed in sheet title.
|
||||
func (f *File) setWorkbook(name string, rid int) {
|
||||
func (f *File) setWorkbook(name string, sheetID, rid int) {
|
||||
content := f.workbookReader()
|
||||
rID := 0
|
||||
for _, v := range content.Sheets.Sheet {
|
||||
t, _ := strconv.Atoi(v.SheetID)
|
||||
if t > rID {
|
||||
rID = t
|
||||
}
|
||||
}
|
||||
rID++
|
||||
content.Sheets.Sheet = append(content.Sheets.Sheet, xlsxSheet{
|
||||
Name: trimSheetName(name),
|
||||
SheetID: strconv.Itoa(rID),
|
||||
SheetID: sheetID,
|
||||
ID: "rId" + strconv.Itoa(rid),
|
||||
})
|
||||
}
|
||||
|
@ -209,13 +211,13 @@ func (f *File) setAppXML() {
|
|||
f.saveFileList("docProps/app.xml", []byte(templateDocpropsApp))
|
||||
}
|
||||
|
||||
// replaceRelationshipsNameSpaceBytes; Some tools that read XLSX files have very strict requirements about the
|
||||
// structure of the input XML. In particular both Numbers on the Mac and SAS
|
||||
// dislike inline XML namespace declarations, or namespace prefixes that don't
|
||||
// match the ones that Excel itself uses. This is a problem because the Go XML
|
||||
// library doesn't multiple namespace declarations in a single element of a
|
||||
// document. This function is a horrible hack to fix that after the XML
|
||||
// marshalling is completed.
|
||||
// replaceRelationshipsNameSpaceBytes; Some tools that read XLSX files have
|
||||
// very strict requirements about the structure of the input XML. In
|
||||
// particular both Numbers on the Mac and SAS dislike inline XML namespace
|
||||
// declarations, or namespace prefixes that don't match the ones that Excel
|
||||
// itself uses. This is a problem because the Go XML library doesn't multiple
|
||||
// namespace declarations in a single element of a document. This function is
|
||||
// a horrible hack to fix that after the XML marshalling is completed.
|
||||
func replaceRelationshipsNameSpaceBytes(workbookMarshal []byte) []byte {
|
||||
oldXmlns := []byte(`<workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">`)
|
||||
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) {
|
|||
if index < 1 {
|
||||
index = 1
|
||||
}
|
||||
index--
|
||||
content := f.workbookReader()
|
||||
if len(content.BookViews.WorkBookView) > 0 {
|
||||
content.BookViews.WorkBookView[0].ActiveTab = index
|
||||
} else {
|
||||
content.BookViews.WorkBookView = append(content.BookViews.WorkBookView, xlsxWorkBookView{
|
||||
ActiveTab: index,
|
||||
})
|
||||
wb := f.workbookReader()
|
||||
for activeTab, sheet := range wb.Sheets.Sheet {
|
||||
if sheet.SheetID == index {
|
||||
if len(wb.BookViews.WorkBookView) > 0 {
|
||||
wb.BookViews.WorkBookView[0].ActiveTab = activeTab
|
||||
} else {
|
||||
wb.BookViews.WorkBookView = append(wb.BookViews.WorkBookView, xlsxWorkBookView{
|
||||
ActiveTab: activeTab,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
index++
|
||||
for idx, name := range f.GetSheetMap() {
|
||||
xlsx := f.workSheetReader(name)
|
||||
if len(xlsx.SheetViews.SheetView) > 0 {
|
||||
xlsx.SheetViews.SheetView[0].TabSelected = false
|
||||
}
|
||||
if index == idx {
|
||||
if len(xlsx.SheetViews.SheetView) > 0 {
|
||||
xlsx.SheetViews.SheetView[0].TabSelected = true
|
||||
|
@ -250,10 +257,6 @@ func (f *File) SetActiveSheet(index int) {
|
|||
TabSelected: true,
|
||||
})
|
||||
}
|
||||
} else {
|
||||
if len(xlsx.SheetViews.SheetView) > 0 {
|
||||
xlsx.SheetViews.SheetView[0].TabSelected = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -261,21 +264,13 @@ func (f *File) SetActiveSheet(index int) {
|
|||
// GetActiveSheetIndex provides a function to get active sheet index of the
|
||||
// XLSX. If not found the active sheet will be return integer 0.
|
||||
func (f *File) GetActiveSheetIndex() int {
|
||||
buffer := bytes.Buffer{}
|
||||
content := f.workbookReader()
|
||||
for _, v := range content.Sheets.Sheet {
|
||||
xlsx := xlsxWorksheet{}
|
||||
buffer.WriteString("xl/worksheets/sheet")
|
||||
buffer.WriteString(strings.TrimPrefix(v.ID, "rId"))
|
||||
buffer.WriteString(".xml")
|
||||
_ = xml.Unmarshal(namespaceStrictToTransitional(f.readXML(buffer.String())), &xlsx)
|
||||
for idx, name := range f.GetSheetMap() {
|
||||
xlsx := f.workSheetReader(name)
|
||||
for _, sheetView := range xlsx.SheetViews.SheetView {
|
||||
if sheetView.TabSelected {
|
||||
ID, _ := strconv.Atoi(strings.TrimPrefix(v.ID, "rId"))
|
||||
return ID
|
||||
return idx
|
||||
}
|
||||
}
|
||||
buffer.Reset()
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
@ -404,8 +399,8 @@ func (f *File) DeleteSheet(name string) {
|
|||
for k, v := range content.Sheets.Sheet {
|
||||
if v.Name == trimSheetName(name) && len(content.Sheets.Sheet) > 1 {
|
||||
content.Sheets.Sheet = append(content.Sheets.Sheet[:k], content.Sheets.Sheet[k+1:]...)
|
||||
sheet := "xl/worksheets/sheet" + strings.TrimPrefix(v.ID, "rId") + ".xml"
|
||||
rels := "xl/worksheets/_rels/sheet" + strings.TrimPrefix(v.ID, "rId") + ".xml.rels"
|
||||
sheet := "xl/worksheets/sheet" + strconv.Itoa(v.SheetID) + ".xml"
|
||||
rels := "xl/worksheets/_rels/sheet" + strconv.Itoa(v.SheetID) + ".xml.rels"
|
||||
target := f.deleteSheetFromWorkbookRels(v.ID)
|
||||
f.deleteSheetFromContentTypes(target)
|
||||
delete(f.sheetMap, name)
|
||||
|
|
BIN
test/Book1.xlsx
BIN
test/Book1.xlsx
Binary file not shown.
|
@ -151,7 +151,7 @@ type xlsxSheets struct {
|
|||
// not checked it for completeness - it does as much as I need.
|
||||
type xlsxSheet struct {
|
||||
Name string `xml:"name,attr,omitempty"`
|
||||
SheetID string `xml:"sheetId,attr,omitempty"`
|
||||
SheetID int `xml:"sheetId,attr,omitempty"`
|
||||
ID string `xml:"http://schemas.openxmlformats.org/officeDocument/2006/relationships id,attr,omitempty"`
|
||||
State string `xml:"state,attr,omitempty"`
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue