xmlWorksheet.go 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419
  1. package xlsx
  2. import (
  3. "encoding/xml"
  4. "strings"
  5. )
  6. // xlsxWorksheet directly maps the worksheet element in the namespace
  7. // http://schemas.openxmlformats.org/spreadsheetml/2006/main -
  8. // currently I have not checked it for completeness - it does as much
  9. // as I need.
  10. type xlsxWorksheet struct {
  11. XMLName xml.Name `xml:"http://schemas.openxmlformats.org/spreadsheetml/2006/main worksheet"`
  12. SheetPr xlsxSheetPr `xml:"sheetPr"`
  13. Dimension xlsxDimension `xml:"dimension"`
  14. SheetViews xlsxSheetViews `xml:"sheetViews"`
  15. SheetFormatPr xlsxSheetFormatPr `xml:"sheetFormatPr"`
  16. Cols *xlsxCols `xml:"cols,omitempty"`
  17. SheetData xlsxSheetData `xml:"sheetData"`
  18. DataValidations *xlsxDataValidations `xml:"dataValidations"`
  19. AutoFilter *xlsxAutoFilter `xml:"autoFilter,omitempty"`
  20. MergeCells *xlsxMergeCells `xml:"mergeCells,omitempty"`
  21. PrintOptions xlsxPrintOptions `xml:"printOptions"`
  22. PageMargins xlsxPageMargins `xml:"pageMargins"`
  23. PageSetUp xlsxPageSetUp `xml:"pageSetup"`
  24. HeaderFooter xlsxHeaderFooter `xml:"headerFooter"`
  25. }
  26. // xlsxHeaderFooter directly maps the headerFooter element in the namespace
  27. // http://schemas.openxmlformats.org/spreadsheetml/2006/main -
  28. // currently I have not checked it for completeness - it does as much
  29. // as I need.
  30. type xlsxHeaderFooter struct {
  31. DifferentFirst bool `xml:"differentFirst,attr"`
  32. DifferentOddEven bool `xml:"differentOddEven,attr"`
  33. OddHeader []xlsxOddHeader `xml:"oddHeader"`
  34. OddFooter []xlsxOddFooter `xml:"oddFooter"`
  35. }
  36. // xlsxOddHeader directly maps the oddHeader element in the namespace
  37. // http://schemas.openxmlformats.org/spreadsheetml/2006/main -
  38. // currently I have not checked it for completeness - it does as much
  39. // as I need.
  40. type xlsxOddHeader struct {
  41. Content string `xml:",chardata"`
  42. }
  43. // xlsxOddFooter directly maps the oddFooter element in the namespace
  44. // http://schemas.openxmlformats.org/spreadsheetml/2006/main -
  45. // currently I have not checked it for completeness - it does as much
  46. // as I need.
  47. type xlsxOddFooter struct {
  48. Content string `xml:",chardata"`
  49. }
  50. // xlsxPageSetUp directly maps the pageSetup element in the namespace
  51. // http://schemas.openxmlformats.org/spreadsheetml/2006/main -
  52. // currently I have not checked it for completeness - it does as much
  53. // as I need.
  54. type xlsxPageSetUp struct {
  55. PaperSize string `xml:"paperSize,attr"`
  56. Scale int `xml:"scale,attr"`
  57. FirstPageNumber int `xml:"firstPageNumber,attr"`
  58. FitToWidth int `xml:"fitToWidth,attr"`
  59. FitToHeight int `xml:"fitToHeight,attr"`
  60. PageOrder string `xml:"pageOrder,attr"`
  61. Orientation string `xml:"orientation,attr"`
  62. UsePrinterDefaults bool `xml:"usePrinterDefaults,attr"`
  63. BlackAndWhite bool `xml:"blackAndWhite,attr"`
  64. Draft bool `xml:"draft,attr"`
  65. CellComments string `xml:"cellComments,attr"`
  66. UseFirstPageNumber bool `xml:"useFirstPageNumber,attr"`
  67. HorizontalDPI float32 `xml:"horizontalDpi,attr"`
  68. VerticalDPI float32 `xml:"verticalDpi,attr"`
  69. Copies int `xml:"copies,attr"`
  70. }
  71. // xlsxPrintOptions directly maps the printOptions element in the namespace
  72. // http://schemas.openxmlformats.org/spreadsheetml/2006/main -
  73. // currently I have not checked it for completeness - it does as much
  74. // as I need.
  75. type xlsxPrintOptions struct {
  76. Headings bool `xml:"headings,attr"`
  77. GridLines bool `xml:"gridLines,attr"`
  78. GridLinesSet bool `xml:"gridLinesSet,attr"`
  79. HorizontalCentered bool `xml:"horizontalCentered,attr"`
  80. VerticalCentered bool `xml:"verticalCentered,attr"`
  81. }
  82. // xlsxPageMargins directly maps the pageMargins element in the namespace
  83. // http://schemas.openxmlformats.org/spreadsheetml/2006/main -
  84. // currently I have not checked it for completeness - it does as much
  85. // as I need.
  86. type xlsxPageMargins struct {
  87. Left float64 `xml:"left,attr"`
  88. Right float64 `xml:"right,attr"`
  89. Top float64 `xml:"top,attr"`
  90. Bottom float64 `xml:"bottom,attr"`
  91. Header float64 `xml:"header,attr"`
  92. Footer float64 `xml:"footer,attr"`
  93. }
  94. // xlsxSheetFormatPr directly maps the sheetFormatPr element in the namespace
  95. // http://schemas.openxmlformats.org/spreadsheetml/2006/main -
  96. // currently I have not checked it for completeness - it does as much
  97. // as I need.
  98. type xlsxSheetFormatPr struct {
  99. DefaultColWidth float64 `xml:"defaultColWidth,attr,omitempty"`
  100. DefaultRowHeight float64 `xml:"defaultRowHeight,attr"`
  101. OutlineLevelCol uint8 `xml:"outlineLevelCol,attr,omitempty"`
  102. OutlineLevelRow uint8 `xml:"outlineLevelRow,attr,omitempty"`
  103. }
  104. // xlsxSheetViews directly maps the sheetViews element in the namespace
  105. // http://schemas.openxmlformats.org/spreadsheetml/2006/main -
  106. // currently I have not checked it for completeness - it does as much
  107. // as I need.
  108. type xlsxSheetViews struct {
  109. SheetView []xlsxSheetView `xml:"sheetView"`
  110. }
  111. // xlsxSheetView directly maps the sheetView element in the namespace
  112. // http://schemas.openxmlformats.org/spreadsheetml/2006/main -
  113. // currently I have not checked it for completeness - it does as much
  114. // as I need.
  115. type xlsxSheetView struct {
  116. WindowProtection bool `xml:"windowProtection,attr"`
  117. ShowFormulas bool `xml:"showFormulas,attr"`
  118. ShowGridLines bool `xml:"showGridLines,attr"`
  119. ShowRowColHeaders bool `xml:"showRowColHeaders,attr"`
  120. ShowZeros bool `xml:"showZeros,attr"`
  121. RightToLeft bool `xml:"rightToLeft,attr"`
  122. TabSelected bool `xml:"tabSelected,attr"`
  123. ShowOutlineSymbols bool `xml:"showOutlineSymbols,attr"`
  124. DefaultGridColor bool `xml:"defaultGridColor,attr"`
  125. View string `xml:"view,attr"`
  126. TopLeftCell string `xml:"topLeftCell,attr"`
  127. ColorId int `xml:"colorId,attr"`
  128. ZoomScale float64 `xml:"zoomScale,attr"`
  129. ZoomScaleNormal float64 `xml:"zoomScaleNormal,attr"`
  130. ZoomScalePageLayoutView float64 `xml:"zoomScalePageLayoutView,attr"`
  131. WorkbookViewId int `xml:"workbookViewId,attr"`
  132. Pane *xlsxPane `xml:"pane"`
  133. Selection []xlsxSelection `xml:"selection"`
  134. }
  135. // xlsxSelection directly maps the selection element in the namespace
  136. // http://schemas.openxmlformats.org/spreadsheetml/2006/main -
  137. // currently I have not checked it for completeness - it does as much
  138. // as I need.
  139. type xlsxSelection struct {
  140. Pane string `xml:"pane,attr"`
  141. ActiveCell string `xml:"activeCell,attr"`
  142. ActiveCellId int `xml:"activeCellId,attr"`
  143. SQRef string `xml:"sqref,attr"`
  144. }
  145. // xlsxSelection directly maps the selection element in the namespace
  146. // http://schemas.openxmlformats.org/spreadsheetml/2006/main -
  147. // currently I have not checked it for completeness - it does as much
  148. // as I need.
  149. type xlsxPane struct {
  150. XSplit float64 `xml:"xSplit,attr"`
  151. YSplit float64 `xml:"ySplit,attr"`
  152. TopLeftCell string `xml:"topLeftCell,attr"`
  153. ActivePane string `xml:"activePane,attr"`
  154. State string `xml:"state,attr"` // Either "split" or "frozen"
  155. }
  156. // xlsxSheetPr directly maps the sheetPr element in the namespace
  157. // http://schemas.openxmlformats.org/spreadsheetml/2006/main -
  158. // currently I have not checked it for completeness - it does as much
  159. // as I need.
  160. type xlsxSheetPr struct {
  161. FilterMode bool `xml:"filterMode,attr"`
  162. PageSetUpPr []xlsxPageSetUpPr `xml:"pageSetUpPr"`
  163. }
  164. // xlsxPageSetUpPr directly maps the pageSetupPr element in the namespace
  165. // http://schemas.openxmlformats.org/spreadsheetml/2006/main -
  166. // currently I have not checked it for completeness - it does as much
  167. // as I need.
  168. type xlsxPageSetUpPr struct {
  169. FitToPage bool `xml:"fitToPage,attr"`
  170. }
  171. // xlsxCols directly maps the cols element in the namespace
  172. // http://schemas.openxmlformats.org/spreadsheetml/2006/main -
  173. // currently I have not checked it for completeness - it does as much
  174. // as I need.
  175. type xlsxCols struct {
  176. Col []xlsxCol `xml:"col"`
  177. }
  178. // xlsxCol directly maps the col element in the namespace
  179. // http://schemas.openxmlformats.org/spreadsheetml/2006/main -
  180. // currently I have not checked it for completeness - it does as much
  181. // as I need.
  182. type xlsxCol struct {
  183. Collapsed bool `xml:"collapsed,attr"`
  184. Hidden bool `xml:"hidden,attr"`
  185. Max int `xml:"max,attr"`
  186. Min int `xml:"min,attr"`
  187. Style int `xml:"style,attr"`
  188. Width float64 `xml:"width,attr"`
  189. CustomWidth bool `xml:"customWidth,attr,omitempty"`
  190. OutlineLevel uint8 `xml:"outlineLevel,attr,omitempty"`
  191. BestFit bool `xml:"bestFit,attr,omitempty"`
  192. Phonetic bool `xml:"phonetic,attr,omitempty"`
  193. }
  194. // xlsxDimension directly maps the dimension element in the namespace
  195. // http://schemas.openxmlformats.org/spreadsheetml/2006/main -
  196. // currently I have not checked it for completeness - it does as much
  197. // as I need.
  198. type xlsxDimension struct {
  199. Ref string `xml:"ref,attr"`
  200. }
  201. // xlsxSheetData directly maps the sheetData element in the namespace
  202. // http://schemas.openxmlformats.org/spreadsheetml/2006/main -
  203. // currently I have not checked it for completeness - it does as much
  204. // as I need.
  205. type xlsxSheetData struct {
  206. XMLName xml.Name `xml:"sheetData"`
  207. Row []xlsxRow `xml:"row"`
  208. }
  209. // xlsxDataValidations excel cell data validation
  210. type xlsxDataValidations struct {
  211. DataValidation []*xlsxDataValidation `xml:"dataValidation"`
  212. Count int `xml:"count,attr"`
  213. }
  214. // xlsxDataValidation
  215. // A single item of data validation defined on a range of the worksheet.
  216. // The list validation type would more commonly be called "a drop down box."
  217. type xlsxDataValidation struct {
  218. // A boolean value indicating whether the data validation allows the use of empty or blank
  219. //entries. 1 means empty entries are OK and do not violate the validation constraints.
  220. AllowBlank bool `xml:"allowBlank,attr,omitempty"`
  221. // A boolean value indicating whether to display the input prompt message.
  222. ShowInputMessage bool `xml:"showInputMessage,attr,omitempty"`
  223. // A boolean value indicating whether to display the error alert message when an invalid
  224. // value has been entered, according to the criteria specified.
  225. ShowErrorMessage bool `xml:"showErrorMessage,attr,omitempty"`
  226. // The style of error alert used for this data validation.
  227. // warning, infomation, or stop
  228. // Stop will prevent the user from entering data that does not pass validation.
  229. ErrorStyle *string `xml:"errorStyle,attr"`
  230. // Title bar text of error alert.
  231. ErrorTitle *string `xml:"errorTitle,attr"`
  232. // The relational operator used with this data validation.
  233. // The possible values for this can be equal, notEqual, lessThan, etc.
  234. // This only applies to certain validation types.
  235. Operator string `xml:"operator,attr,omitempty"`
  236. // Message text of error alert.
  237. Error *string `xml:"error,attr"`
  238. // Title bar text of input prompt.
  239. PromptTitle *string `xml:"promptTitle,attr"`
  240. // Message text of input prompt.
  241. Prompt *string `xml:"prompt,attr"`
  242. // The type of data validation.
  243. // none, custom, date, decimal, list, textLength, time, whole
  244. Type string `xml:"type,attr"`
  245. // Range over which data validation is applied.
  246. // Cell or range, eg: A1 OR A1:A20
  247. Sqref string `xml:"sqref,attr,omitempty"`
  248. // The first formula in the Data Validation dropdown. It is used as a bounds for 'between' and
  249. // 'notBetween' relational operators, and the only formula used for other relational operators
  250. // (equal, notEqual, lessThan, lessThanOrEqual, greaterThan, greaterThanOrEqual), or for custom
  251. // or list type data validation. The content can be a formula or a constant or a list series (comma separated values).
  252. Formula1 string `xml:"formula1"`
  253. // The second formula in the DataValidation dropdown. It is used as a bounds for 'between' and
  254. // 'notBetween' relational operators only.
  255. Formula2 string `xml:"formula2,omitempty"`
  256. }
  257. // xlsxRow directly maps the row element in the namespace
  258. // http://schemas.openxmlformats.org/spreadsheetml/2006/main -
  259. // currently I have not checked it for completeness - it does as much
  260. // as I need.
  261. type xlsxRow struct {
  262. R int `xml:"r,attr"`
  263. Spans string `xml:"spans,attr,omitempty"`
  264. Hidden bool `xml:"hidden,attr,omitempty"`
  265. C []xlsxC `xml:"c"`
  266. Ht string `xml:"ht,attr,omitempty"`
  267. CustomHeight bool `xml:"customHeight,attr,omitempty"`
  268. OutlineLevel uint8 `xml:"outlineLevel,attr,omitempty"`
  269. }
  270. type xlsxAutoFilter struct {
  271. Ref string `xml:"ref,attr"`
  272. }
  273. type xlsxMergeCell struct {
  274. Ref string `xml:"ref,attr"` // ref: horiz "A1:C1", vert "B3:B6", both "D3:G4"
  275. }
  276. type xlsxMergeCells struct {
  277. XMLName xml.Name //`xml:"mergeCells,omitempty"`
  278. Count int `xml:"count,attr,omitempty"`
  279. Cells []xlsxMergeCell `xml:"mergeCell,omitempty"`
  280. }
  281. // Return the cartesian extent of a merged cell range from its origin
  282. // cell (the closest merged cell to the to left of the sheet.
  283. func (mc *xlsxMergeCells) getExtent(cellRef string) (int, int, error) {
  284. if mc == nil {
  285. return 0, 0, nil
  286. }
  287. for _, cell := range mc.Cells {
  288. if strings.HasPrefix(cell.Ref, cellRef+cellRangeChar) {
  289. parts := strings.Split(cell.Ref, cellRangeChar)
  290. startx, starty, err := GetCoordsFromCellIDString(parts[0])
  291. if err != nil {
  292. return -1, -1, err
  293. }
  294. endx, endy, err := GetCoordsFromCellIDString(parts[1])
  295. if err != nil {
  296. return -2, -2, err
  297. }
  298. return endx - startx, endy - starty, nil
  299. }
  300. }
  301. return 0, 0, nil
  302. }
  303. // xlsxC directly maps the c element in the namespace
  304. // http://schemas.openxmlformats.org/spreadsheetml/2006/main -
  305. // currently I have not checked it for completeness - it does as much
  306. // as I need.
  307. type xlsxC struct {
  308. XMLName xml.Name
  309. R string `xml:"r,attr"` // Cell ID, e.g. A1
  310. S int `xml:"s,attr,omitempty"` // Style reference.
  311. T string `xml:"t,attr,omitempty"` // Type.
  312. F *xlsxF `xml:"f,omitempty"` // Formula
  313. V string `xml:"v,omitempty"` // Value
  314. Is *xlsxSI `xml:"is,omitempty"` // Inline String.
  315. }
  316. // xlsxF directly maps the f element in the namespace
  317. // http://schemas.openxmlformats.org/spreadsheetml/2006/main -
  318. // currently I have not checked it for completeness - it does as much
  319. // as I need.
  320. type xlsxF struct {
  321. Content string `xml:",chardata"`
  322. T string `xml:"t,attr,omitempty"` // Formula type
  323. Ref string `xml:"ref,attr,omitempty"` // Shared formula ref
  324. Si int `xml:"si,attr,omitempty"` // Shared formula index
  325. }
  326. // Create a new XLSX Worksheet with default values populated.
  327. // Strictly for internal use only!
  328. func newXlsxWorksheet() (worksheet *xlsxWorksheet) {
  329. worksheet = &xlsxWorksheet{}
  330. worksheet.SheetPr.FilterMode = false
  331. worksheet.SheetPr.PageSetUpPr = make([]xlsxPageSetUpPr, 1)
  332. worksheet.SheetPr.PageSetUpPr[0] = xlsxPageSetUpPr{FitToPage: false}
  333. worksheet.SheetViews.SheetView = make([]xlsxSheetView, 1)
  334. worksheet.SheetViews.SheetView[0] = xlsxSheetView{
  335. ColorId: 64,
  336. DefaultGridColor: true,
  337. RightToLeft: false,
  338. Selection: make([]xlsxSelection, 1),
  339. ShowFormulas: false,
  340. ShowGridLines: true,
  341. ShowOutlineSymbols: true,
  342. ShowRowColHeaders: true,
  343. ShowZeros: true,
  344. TabSelected: false,
  345. TopLeftCell: "A1",
  346. View: "normal",
  347. WindowProtection: false,
  348. WorkbookViewId: 0,
  349. ZoomScale: 100,
  350. ZoomScaleNormal: 100,
  351. ZoomScalePageLayoutView: 100}
  352. worksheet.SheetViews.SheetView[0].Selection[0] = xlsxSelection{
  353. Pane: "topLeft",
  354. ActiveCell: "A1",
  355. ActiveCellId: 0,
  356. SQRef: "A1"}
  357. worksheet.SheetFormatPr.DefaultRowHeight = 12.85
  358. worksheet.PrintOptions.Headings = false
  359. worksheet.PrintOptions.GridLines = false
  360. worksheet.PrintOptions.GridLinesSet = true
  361. worksheet.PrintOptions.HorizontalCentered = false
  362. worksheet.PrintOptions.VerticalCentered = false
  363. worksheet.PageMargins.Left = 0.7875
  364. worksheet.PageMargins.Right = 0.7875
  365. worksheet.PageMargins.Top = 1.05277777777778
  366. worksheet.PageMargins.Bottom = 1.05277777777778
  367. worksheet.PageMargins.Header = 0.7875
  368. worksheet.PageMargins.Footer = 0.7875
  369. worksheet.PageSetUp.PaperSize = "9"
  370. worksheet.PageSetUp.Scale = 100
  371. worksheet.PageSetUp.FirstPageNumber = 1
  372. worksheet.PageSetUp.FitToWidth = 1
  373. worksheet.PageSetUp.FitToHeight = 1
  374. worksheet.PageSetUp.PageOrder = "downThenOver"
  375. worksheet.PageSetUp.Orientation = "portrait"
  376. worksheet.PageSetUp.UsePrinterDefaults = false
  377. worksheet.PageSetUp.BlackAndWhite = false
  378. worksheet.PageSetUp.Draft = false
  379. worksheet.PageSetUp.CellComments = "none"
  380. worksheet.PageSetUp.UseFirstPageNumber = true
  381. worksheet.PageSetUp.HorizontalDPI = 300
  382. worksheet.PageSetUp.VerticalDPI = 300
  383. worksheet.PageSetUp.Copies = 1
  384. worksheet.HeaderFooter.OddHeader = make([]xlsxOddHeader, 1)
  385. worksheet.HeaderFooter.OddHeader[0] = xlsxOddHeader{Content: `&C&"Times New Roman,Regular"&12&A`}
  386. worksheet.HeaderFooter.OddFooter = make([]xlsxOddFooter, 1)
  387. worksheet.HeaderFooter.OddFooter[0] = xlsxOddFooter{Content: `&C&"Times New Roman,Regular"&12Page &P`}
  388. return
  389. }