The basic unit of spreadsheet data is the cell, which can be embellished with style data, e.g.
{:data-format :percent, :font {:bold true :font-height-in-points 10}}
The goal of the style map is to reuse all of the functionality built in to the underlying Apache POI objects, but with immutable data structures.
The primary advantage is the ease with which we can merge styles as maps rather than trying to create some new POI object out of two other objects, reading and combining all of their attributes and nested attributes.
Style map data are representative of nested calls to the corresponding setter
methods in the Apache POI framework starting with a CellStyle
object. That
is, the above example is roughly interpreted as:
;; A CellStyle POI object created under the hood during rendering (let [cell-style ...]
;; The style map attributes are converted to camel cased setters
(doto cell-style
(.setDataFormat :percent)
(.setFont
(doto <create a font>
(.setBold true)
(.setFontHeightInPoints 10)))))
The two nontrivial challenges are
Both are solved with the coerce-to-obj
multimethod specifying how to
coerce different attributes to POI objects, which has the shape
(fn [workbook attribute value] => Object)
and dispatches on the attribute
(a keyword).
We coerce key value pairs to objects from the bottom of the style map upwards, meaning that by the time coerce-to-obj is being invoked for some attribute, any nested attributes in the value have already been coerced.
A more nuanced representation of how the style map 'expands':
;; {:data-format :percent, :font {:bold true :font-height-in-points 10}}} ;; expands to (let [cell-style ..., workbook ...] ;; POI objects created during rendering (doto cell-style (.setDataFormat (coerce-to-obj workbook :data-format :percent)) ;; The {:bold true :font-height-in-points 10} expands recursively (.setFont (coerce-to-obj workbook :font {:bold true :font-height-in-points 10}))))
The basic unit of spreadsheet data is the cell, which can be embellished with style data, e.g. {:data-format :percent, :font {:bold true :font-height-in-points 10}} The goal of the style map is to reuse all of the functionality built in to the underlying Apache POI objects, but with immutable data structures. The primary advantage is the ease with which we can merge styles as maps rather than trying to create some new POI object out of two other objects, reading and combining all of their attributes and nested attributes. ## Mechanics Style map data are representative of nested calls to the corresponding setter methods in the Apache POI framework starting with a `CellStyle` object. That is, the above example is roughly interpreted as: ;; A CellStyle POI object created under the hood during rendering (let [cell-style ...] ;; The style map attributes are converted to camel cased setters (doto cell-style (.setDataFormat :percent) (.setFont (doto <create a font> (.setBold true) (.setFontHeightInPoints 10))))) The two nontrivial challenges are - creating nested objects, e.g. (.setFont cell-style <font>) needs to be called with a POI Font object; and - translating keywords like :percent to POI objects. Both are solved with the `coerce-to-obj` multimethod specifying how to coerce different attributes to POI objects, which has the shape (fn [workbook attribute value] => Object) and dispatches on the `attribute` (a keyword). We coerce key value pairs to objects from the bottom of the style map upwards, meaning that by the time coerce-to-obj is being invoked for some attribute, any nested attributes in the value have already been coerced. A more nuanced representation of how the style map 'expands': ;; {:data-format :percent, :font {:bold true :font-height-in-points 10}}} ;; expands to (let [cell-style ..., workbook ...] ;; POI objects created during rendering (doto cell-style (.setDataFormat (coerce-to-obj workbook :data-format :percent)) ;; The {:bold true :font-height-in-points 10} expands recursively (.setFont (coerce-to-obj workbook :font {:bold true :font-height-in-points 10}))))
(build-style workbook attrs)
Create a CellStyle from the given attrs using the given workbook CellStyle attributes are anything that can be set with .setCamelCasedAttribute on a CellStyle object, including {:data-format string or keyword :font { ... font attrs ... } :wrap-text boolean :hidden boolean :alignment org.apache.poi.ss.usermodel.HorizontalAlignment :border-[bottom|left|right|top] org.apache.poi.ss.usermodel.BorderStyle}
Any of the attributes can be java objects. Alternatively, if a coerce-to-obj
implementation is provided for some attribute (e.g. :font), the attribute can
be specified as data.
Create a CellStyle from the given attrs using the given workbook CellStyle attributes are anything that can be set with .setCamelCasedAttribute on a CellStyle object, including {:data-format string or keyword :font { ... font attrs ... } :wrap-text boolean :hidden boolean :alignment org.apache.poi.ss.usermodel.HorizontalAlignment :border-[bottom|left|right|top] org.apache.poi.ss.usermodel.BorderStyle} Any of the attributes can be java objects. Alternatively, if a `coerce-to-obj` implementation is provided for some attribute (e.g. :font), the attribute can be specified as data.
For some keyword attribute of a CellStyle object, attempt to coerce clojure data (either a keyword or a map) to the Java object the setter is expecting.
This allows nesting of style specification maps {:font {:bold true, :color :yellow}} so that when it's time to generate a CellStyle object, we can say that we know how to go from an attribute map to a Font object for :font attributes, from a keyword to a Color object for :color attributes, etc.
For some keyword attribute of a CellStyle object, attempt to coerce clojure data (either a keyword or a map) to the Java object the setter is expecting. This allows nesting of style specification maps {:font {:bold true, :color :yellow}} so that when it's time to generate a CellStyle object, we can say that we know how to go from an attribute map to a Font object for :font attributes, from a keyword to a Color object for :color attributes, etc.
(rgb-color r g b)
Create an XSSFColor object from the given r g b values.
Create an XSSFColor object from the given r g b values.
cljdoc is a website building & hosting documentation for Clojure/Script libraries
× close