docProps.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. // Copyright 2016 - 2023 The excelize Authors. All rights reserved. Use of
  2. // this source code is governed by a BSD-style license that can be found in
  3. // the LICENSE file.
  4. //
  5. // Package excelize providing a set of functions that allow you to write to and
  6. // read from XLAM / XLSM / XLSX / XLTM / XLTX files. Supports reading and
  7. // writing spreadsheet documents generated by Microsoft Excel™ 2007 and later.
  8. // Supports complex components by high compatibility, and provided streaming
  9. // API for generating or reading data from a worksheet with huge amounts of
  10. // data. This library needs Go version 1.16 or later.
  11. package excelize
  12. import (
  13. "bytes"
  14. "encoding/xml"
  15. "io"
  16. "reflect"
  17. )
  18. // SetAppProps provides a function to set document application properties. The
  19. // properties that can be set are:
  20. //
  21. // Property | Description
  22. // -------------------+--------------------------------------------------------------------------
  23. // Application | The name of the application that created this document.
  24. // |
  25. // ScaleCrop | Indicates the display mode of the document thumbnail. Set this element
  26. // | to 'true' to enable scaling of the document thumbnail to the display. Set
  27. // | this element to 'false' to enable cropping of the document thumbnail to
  28. // | show only sections that will fit the display.
  29. // |
  30. // DocSecurity | Security level of a document as a numeric value. Document security is
  31. // | defined as:
  32. // | 1 - Document is password protected.
  33. // | 2 - Document is recommended to be opened as read-only.
  34. // | 3 - Document is enforced to be opened as read-only.
  35. // | 4 - Document is locked for annotation.
  36. // |
  37. // Company | The name of a company associated with the document.
  38. // |
  39. // LinksUpToDate | Indicates whether hyperlinks in a document are up-to-date. Set this
  40. // | element to 'true' to indicate that hyperlinks are updated. Set this
  41. // | element to 'false' to indicate that hyperlinks are outdated.
  42. // |
  43. // HyperlinksChanged | Specifies that one or more hyperlinks in this part were updated
  44. // | exclusively in this part by a producer. The next producer to open this
  45. // | document shall update the hyperlink relationships with the new
  46. // | hyperlinks specified in this part.
  47. // |
  48. // AppVersion | Specifies the version of the application which produced this document.
  49. // | The content of this element shall be of the form XX.YYYY where X and Y
  50. // | represent numerical values, or the document shall be considered
  51. // | non-conformant.
  52. //
  53. // For example:
  54. //
  55. // err := f.SetAppProps(&excelize.AppProperties{
  56. // Application: "Microsoft Excel",
  57. // ScaleCrop: true,
  58. // DocSecurity: 3,
  59. // Company: "Company Name",
  60. // LinksUpToDate: true,
  61. // HyperlinksChanged: true,
  62. // AppVersion: "16.0000",
  63. // })
  64. func (f *File) SetAppProps(appProperties *AppProperties) error {
  65. var (
  66. app *xlsxProperties
  67. err error
  68. field string
  69. fields []string
  70. immutable, mutable reflect.Value
  71. output []byte
  72. )
  73. app = new(xlsxProperties)
  74. if err = f.xmlNewDecoder(bytes.NewReader(namespaceStrictToTransitional(f.readXML(defaultXMLPathDocPropsApp)))).
  75. Decode(app); err != nil && err != io.EOF {
  76. return err
  77. }
  78. fields = []string{"Application", "ScaleCrop", "DocSecurity", "Company", "LinksUpToDate", "HyperlinksChanged", "AppVersion"}
  79. immutable, mutable = reflect.ValueOf(*appProperties), reflect.ValueOf(app).Elem()
  80. for _, field = range fields {
  81. immutableField := immutable.FieldByName(field)
  82. switch immutableField.Kind() {
  83. case reflect.Bool:
  84. mutable.FieldByName(field).SetBool(immutableField.Bool())
  85. case reflect.Int:
  86. mutable.FieldByName(field).SetInt(immutableField.Int())
  87. default:
  88. mutable.FieldByName(field).SetString(immutableField.String())
  89. }
  90. }
  91. app.Vt = NameSpaceDocumentPropertiesVariantTypes.Value
  92. output, err = xml.Marshal(app)
  93. f.saveFileList(defaultXMLPathDocPropsApp, output)
  94. return err
  95. }
  96. // GetAppProps provides a function to get document application properties.
  97. func (f *File) GetAppProps() (ret *AppProperties, err error) {
  98. app := new(xlsxProperties)
  99. if err = f.xmlNewDecoder(bytes.NewReader(namespaceStrictToTransitional(f.readXML(defaultXMLPathDocPropsApp)))).
  100. Decode(app); err != nil && err != io.EOF {
  101. return
  102. }
  103. ret, err = &AppProperties{
  104. Application: app.Application,
  105. ScaleCrop: app.ScaleCrop,
  106. DocSecurity: app.DocSecurity,
  107. Company: app.Company,
  108. LinksUpToDate: app.LinksUpToDate,
  109. HyperlinksChanged: app.HyperlinksChanged,
  110. AppVersion: app.AppVersion,
  111. }, nil
  112. return
  113. }
  114. // SetDocProps provides a function to set document core properties. The
  115. // properties that can be set are:
  116. //
  117. // Property | Description
  118. // ----------------+-----------------------------------------------------------
  119. // Title | The name given to the resource.
  120. // |
  121. // Subject | The topic of the content of the resource.
  122. // |
  123. // Creator | An entity primarily responsible for making the content of
  124. // | the resource.
  125. // |
  126. // Keywords | A delimited set of keywords to support searching and
  127. // | indexing. This is typically a list of terms that are not
  128. // | available elsewhere in the properties.
  129. // |
  130. // Description | An explanation of the content of the resource.
  131. // |
  132. // LastModifiedBy | The user who performed the last modification. The
  133. // | identification is environment-specific.
  134. // |
  135. // Language | The language of the intellectual content of the resource.
  136. // |
  137. // Identifier | An unambiguous reference to the resource within a given
  138. // | context.
  139. // |
  140. // Revision | The topic of the content of the resource.
  141. // |
  142. // ContentStatus | The status of the content. For example: Values might
  143. // | include "Draft", "Reviewed" and "Final"
  144. // |
  145. // Category | A categorization of the content of this package.
  146. // |
  147. // Version | The version number. This value is set by the user or by
  148. // | the application.
  149. // |
  150. // Created | The created time of the content of the resource which
  151. // | represent in ISO 8601 UTC format, for example
  152. // | "2019-06-04T22:00:10Z".
  153. // |
  154. // Modified | The modified time of the content of the resource which
  155. // | represent in ISO 8601 UTC format, for example
  156. // | "2019-06-04T22:00:10Z".
  157. // |
  158. //
  159. // For example:
  160. //
  161. // err := f.SetDocProps(&excelize.DocProperties{
  162. // Category: "category",
  163. // ContentStatus: "Draft",
  164. // Created: "2019-06-04T22:00:10Z",
  165. // Creator: "Go Excelize",
  166. // Description: "This file created by Go Excelize",
  167. // Identifier: "xlsx",
  168. // Keywords: "Spreadsheet",
  169. // LastModifiedBy: "Go Author",
  170. // Modified: "2019-06-04T22:00:10Z",
  171. // Revision: "0",
  172. // Subject: "Test Subject",
  173. // Title: "Test Title",
  174. // Language: "en-US",
  175. // Version: "1.0.0",
  176. // })
  177. func (f *File) SetDocProps(docProperties *DocProperties) error {
  178. var (
  179. core *decodeCoreProperties
  180. err error
  181. field, val string
  182. fields []string
  183. immutable, mutable reflect.Value
  184. newProps *xlsxCoreProperties
  185. output []byte
  186. )
  187. core = new(decodeCoreProperties)
  188. if err = f.xmlNewDecoder(bytes.NewReader(namespaceStrictToTransitional(f.readXML(defaultXMLPathDocPropsCore)))).
  189. Decode(core); err != nil && err != io.EOF {
  190. return err
  191. }
  192. newProps = &xlsxCoreProperties{
  193. Dc: NameSpaceDublinCore,
  194. Dcterms: NameSpaceDublinCoreTerms,
  195. Dcmitype: NameSpaceDublinCoreMetadataInitiative,
  196. XSI: NameSpaceXMLSchemaInstance,
  197. Title: core.Title,
  198. Subject: core.Subject,
  199. Creator: core.Creator,
  200. Keywords: core.Keywords,
  201. Description: core.Description,
  202. LastModifiedBy: core.LastModifiedBy,
  203. Language: core.Language,
  204. Identifier: core.Identifier,
  205. Revision: core.Revision,
  206. ContentStatus: core.ContentStatus,
  207. Category: core.Category,
  208. Version: core.Version,
  209. }
  210. if core.Created != nil {
  211. newProps.Created = &xlsxDcTerms{Type: core.Created.Type, Text: core.Created.Text}
  212. }
  213. if core.Modified != nil {
  214. newProps.Modified = &xlsxDcTerms{Type: core.Modified.Type, Text: core.Modified.Text}
  215. }
  216. fields = []string{
  217. "Category", "ContentStatus", "Creator", "Description", "Identifier", "Keywords",
  218. "LastModifiedBy", "Revision", "Subject", "Title", "Language", "Version",
  219. }
  220. immutable, mutable = reflect.ValueOf(*docProperties), reflect.ValueOf(newProps).Elem()
  221. for _, field = range fields {
  222. if val = immutable.FieldByName(field).String(); val != "" {
  223. mutable.FieldByName(field).SetString(val)
  224. }
  225. }
  226. if docProperties.Created != "" {
  227. newProps.Created = &xlsxDcTerms{Type: "dcterms:W3CDTF", Text: docProperties.Created}
  228. }
  229. if docProperties.Modified != "" {
  230. newProps.Modified = &xlsxDcTerms{Type: "dcterms:W3CDTF", Text: docProperties.Modified}
  231. }
  232. output, err = xml.Marshal(newProps)
  233. f.saveFileList(defaultXMLPathDocPropsCore, output)
  234. return err
  235. }
  236. // GetDocProps provides a function to get document core properties.
  237. func (f *File) GetDocProps() (ret *DocProperties, err error) {
  238. core := new(decodeCoreProperties)
  239. if err = f.xmlNewDecoder(bytes.NewReader(namespaceStrictToTransitional(f.readXML(defaultXMLPathDocPropsCore)))).
  240. Decode(core); err != nil && err != io.EOF {
  241. return
  242. }
  243. ret, err = &DocProperties{
  244. Category: core.Category,
  245. ContentStatus: core.ContentStatus,
  246. Creator: core.Creator,
  247. Description: core.Description,
  248. Identifier: core.Identifier,
  249. Keywords: core.Keywords,
  250. LastModifiedBy: core.LastModifiedBy,
  251. Revision: core.Revision,
  252. Subject: core.Subject,
  253. Title: core.Title,
  254. Language: core.Language,
  255. Version: core.Version,
  256. }, nil
  257. if core.Created != nil {
  258. ret.Created = core.Created.Text
  259. }
  260. if core.Modified != nil {
  261. ret.Modified = core.Modified.Text
  262. }
  263. return
  264. }