All Projects → mjul → Docjure

mjul / Docjure

Licence: mit
Read and write Office documents from Clojure

Programming Languages

clojure
4091 projects

Projects that are alternatives of or similar to Docjure

Desktopeditors
An office suite that combines text, spreadsheet and presentation editors allowing to create, view and edit local documents
Stars: ✭ 1,008 (+97.65%)
Mutual labels:  excel, spreadsheet, xlsx, xls
Sheetjs
📗 SheetJS Community Edition -- Spreadsheet Data Toolkit
Stars: ✭ 28,479 (+5484.12%)
Mutual labels:  excel, spreadsheet, xlsx, xls
spreadsheet
Yii2 extension for export to Excel
Stars: ✭ 79 (-84.51%)
Mutual labels:  excel, xlsx, xls, spreadsheet
xltpl
A python module to generate xls/x files from a xls/x template.
Stars: ✭ 46 (-90.98%)
Mutual labels:  excel, xlsx, xls, spreadsheet
Test files
📚 SheetJS Test Files (XLS/XLSX/XLSB and other spreadsheet formats)
Stars: ✭ 150 (-70.59%)
Mutual labels:  excel, spreadsheet, xlsx, xls
Documentbuilder
ONLYOFFICE Document Builder is powerful text, spreadsheet, presentation and PDF generating tool
Stars: ✭ 61 (-88.04%)
Mutual labels:  excel, spreadsheet, xlsx, xls
Readxl
Read excel files (.xls and .xlsx) into R 🖇
Stars: ✭ 585 (+14.71%)
Mutual labels:  excel, spreadsheet, xlsx, xls
Phpspreadsheet
A pure PHP library for reading and writing spreadsheet files
Stars: ✭ 10,627 (+1983.73%)
Mutual labels:  excel, spreadsheet, xlsx, xls
Documentserver
ONLYOFFICE Document Server is an online office suite comprising viewers and editors for texts, spreadsheets and presentations, fully compatible with Office Open XML formats: .docx, .xlsx, .pptx and enabling collaborative editing in real time.
Stars: ✭ 2,335 (+357.84%)
Mutual labels:  excel, spreadsheet, xlsx, xls
J
❌ Multi-format spreadsheet CLI (now merged in http://github.com/sheetjs/js-xlsx )
Stars: ✭ 343 (-32.75%)
Mutual labels:  excel, spreadsheet, xlsx, xls
eec
A fast and lower memory excel write/read tool.一个非POI底层,支持流式处理的高效且超低内存的Excel读写工具
Stars: ✭ 93 (-81.76%)
Mutual labels:  excel, xlsx, xls
xlsx reader
A production-ready XLSX file reader for Elixir.
Stars: ✭ 46 (-90.98%)
Mutual labels:  excel, xlsx, spreadsheet
umya-spreadsheet
A pure rust library for reading and writing spreadsheet files
Stars: ✭ 79 (-84.51%)
Mutual labels:  excel, xlsx, spreadsheet
Easyexcel
快速、简单避免OOM的java处理Excel工具
Stars: ✭ 22,133 (+4239.8%)
Mutual labels:  excel, xlsx, xls
Unioffice
Pure go library for creating and processing Office Word (.docx), Excel (.xlsx) and Powerpoint (.pptx) documents
Stars: ✭ 3,111 (+510%)
Mutual labels:  excel, spreadsheet, xlsx
Dexiom.EPPlusExporter
A very simple, yet incredibly powerfull library to generate Excel documents out of objects, arrays, lists, collections, etc.
Stars: ✭ 19 (-96.27%)
Mutual labels:  excel, xlsx, spreadsheet
sheet2dict
Simple XLSX and CSV to dictionary converter
Stars: ✭ 206 (-59.61%)
Mutual labels:  excel, xlsx, spreadsheet
fxl.js
ƛ fxl.js is a data-oriented JavaScript spreadsheet library. It provides a way to build spreadsheets using modular, lego-like blocks.
Stars: ✭ 27 (-94.71%)
Mutual labels:  excel, xlsx, spreadsheet
fxl
fxl is a Clojure spreadsheet library
Stars: ✭ 117 (-77.06%)
Mutual labels:  excel, xlsx, spreadsheet
spark-hadoopoffice-ds
A Spark datasource for the HadoopOffice library
Stars: ✭ 36 (-92.94%)
Mutual labels:  excel, xlsx, xls

Docjure

Docjure makes reading and writing Office Excel spreadsheet documents in Clojure easy.

Usage

Example: Read a Price List spreadsheet

(use 'dk.ative.docjure.spreadsheet)

;; Load a spreadsheet and read the first two columns from the
;; price list sheet:
(->> (load-workbook "spreadsheet.xlsx")
     (select-sheet "Price List")
     (select-columns {:A :name, :B :price}))

;=> [{:name "Foo Widget", :price 100}, {:name "Bar Widget", :price 200}]

Example: Read a single cell

If you want to read a single cell value, you can use the select-cell function which takes an Excel-style cell reference (A2) and returns the cell. In order to get the actual value, use read-cell

(use 'dk.ative.docjure.spreadsheet)
(read-cell
 (->> (load-workbook "spreadsheet.xlsx")
      (select-sheet "Price List")
      (select-cell "A1")))

Example: Load a Workbook from a Resource

This example loads a workbook from a named file. In the case of running in the application server, the file typically resides in the resources directory, and it's not on the caller's path. To cover this scenario, we provide the function 'load-workbook-from-resource' that takes a named resource as the parameter. After a minor modification, the same example will look like:

(->> (load-workbook-from-resource "spreadsheet.xlsx")
     (select-sheet "Price List")
     (select-columns {:A :name, :B :price}))

Example: Load a Workbook from a Stream

The function 'load-workbook' is a multimethod, and the first example takes a file name as a parameter. The overloaded version of 'load-workbook' takes an InputStream. This may be useful when uploading a workbook to the server over HTTP connection as multipart form data. In this case, the web framework passes a byte buffer, and the example should be modified as (note that you have to use 'with-open' to ensure that the stream will be closed):


(with-open [stream (clojure.java.io/input-stream bytes)]
  (->> (load-workbook stream)
       (select-sheet "Price List")
       (select-columns {:A :name, :B :price})))

Example: Create a spreadsheet

This example creates a spreadsheet with a single sheet named "Price List". It has three rows. We apply a style of yellow background colour and bold font to the top header row, then save the spreadsheet.

(use 'dk.ative.docjure.spreadsheet)

;; Create a spreadsheet and save it
(let [wb (create-workbook "Price List"
                          [["Name" "Price"]
                           ["Foo Widget" 100]
                           ["Bar Widget" 200]])
      sheet (select-sheet "Price List" wb)
      header-row (first (row-seq sheet))]
  (set-row-style! header-row (create-cell-style! wb {:background :yellow,
                                                     :font {:bold true}}))
  (save-workbook! "spreadsheet.xlsx" wb))

Example: Create a workbook with multiple sheets

This example creates a spreadsheet with multiple sheets. Simply add more sheet-name and data pairs. To create a sheet with no data, pass nil as the data argument.

(use 'dk.ative.docjure.spreadsheet)

;; Create a spreadsheet and save it
(let [wb (create-workbook "Squares"
                          [["N" "N^2"]
                           [1 1]
                           [2 4]
                           [3 9]]
                          "Cubes"
                          [["N" "N^3"]
                           [1 1]
                           [2 8]
                           [3 27]])]
   (save-workbook! "exponents.xlsx" wb))

Example: Use Excel Formulas in Clojure

Docjure allows you not only to evaluate a formula cell in a speadsheet, it also provides a way of exposing a formula in a cell as a Clojure function using the cell-fn function.

(use 'dk.ative.docjure.spreadsheet)
;; Load a speadsheet and take the first sheet, construct a function from cell A2, taking
;; A1 as input.
(def formula-from-a2 (cell-fn "A2"
                                  (first (sheet-seq (load-workbook "spreadsheet.xlsx")))
                                  "A1"))

;; Returns value of cell A2, as if value in cell A1 were 1.0
(formula-from-a2 1.0)

Example: Handling Error Cells

If the spreadsheet being read contains cells with errors the default behaviour of the library is to return a keyword representing the error as the cell value.

For example, given a spreadsheet with errors:

(use 'dk.ative.docjure.spreadsheet)

(def sample-cells (->> (load-workbook "spreadsheet.xlsx")
                       (sheet-seq)
                       (mapcat cell-seq)))

sample-cells

;=> (#<XSSFCell 15.0> #<XSSFCell NA()> #<XSSFCell 35.0> #<XSSFCell 13/0> #<XSSFCell 33.0> #<XSSFCell 96.0>)

Reading error cells, or cells that evaluate to an error (e.g. divide by zero) returns a keyword representing the type of error from read-cell.

(->> sample-cells
     (map read-cell))

;=> (15.0 :NA 35.0 :DIV0 33.0 96.0)

How you handle errors will depend on your application. You may want to replace specific errors with a default value and remove others for example:

(->> sample-cells
     (map read-cell)
     (replace {:DIV0 0.0})
     (remove keyword?))

;=> (15.0 35.0 0.0 33.0 96.0)

The following is a list of all possible error values:

#{:VALUE :DIV0 :CIRCULAR_REF :REF :NUM :NULL :FUNCTION_NOT_IMPLEMENTED :NAME :NA}

Example: Iterating over spreadsheet data

A note on sparse data

It's worth understanding a bit about the underlying structure of a spreadsheet before you start iterating over the contents.

Spreadsheets are designed to be sparse - not all rows in the spreadsheet must physically exist, and not all cells in a row must physically exist. This is how you can create data at ZZ:65535 without using huge amounts of storage.

Thus each cell can be in 3 states - with data, blank, or nonexistent (null). There's a special type CellType.BLANK for blank cells, but missing cells are just returned as nil.

Similarly rows can exist with cells, or exist but be empty, or they can not exist at all.

Prior to Docjure 1.11 the iteration functions wrapped the underlying Apache POI iterators, which skipped over missing data - this could cause surprising behaviour, especially when there were missing cells inside tabular data.

Since Docjure 1.11 iteration now returns nil values for missing rows and cells - this is a breaking change - any code that calls row-seq or cell-seq now needs to deal with possible nil values.

Iterating over rows

You can iterate over all the rows in a worksheet with row-seq:

(->> (load-workbook "test.xls")
     (select-sheet "first")
     row-seq)

This will return a sequence of org.apache.poi.usermodel.Row objects, or nil for any missing rows. You can use (remove nil? (row-seq ...) ) if you are happy to ignore missing rows, but then be aware the nth result in the sequence might not match the nth row in the spreadsheet.

Iterating over cells

You can iterate over all the cells in a row with cell-seq - this returns a sequence of org.apache.poi.usermodel.Cell objects, or nil for missing cells. Note that (read-cell nil) returns nil so it's safe to apply read-cell to the results of cell-seq

(->> (load-workbook "test.xls")
     (select-sheet "first")
     row-seq
     (remove nil?)
     (map cell-seq)
     (map #(map read-cell %)))

For example, if you run the above snippet on a sparse spreadsheet like:

First Name Middle Name Last Name
Edger Allen Poe
(missing row)
John (missing) Smith

Then it will return:

(("First Name" "Middle Name" "Last Name")
 ("Edger" "Allen" "Poe")
 ("John" nil "Smith"))

Automatically get the Docjure jar from Clojars

The Docjure jar is distributed on Clojars. Here you can find both release builds and snapshot builds of pre-release versions.

If you are using the Leiningen build tool just add this line to the :dependencies list in project.clj to use it:

[dk.ative/docjure "1.14.0"]

Remember to issue the 'lein deps' command to download it.

Example project.clj for using Docjure 1.14.0

(defproject some.cool/project "1.0.0-SNAPSHOT"
      :description "Spreadsheet magic using Docjure"
      :dependencies [[org.clojure/clojure "1.10.0"]
                     [dk.ative/docjure "1.14.0"]])

Installation for Contributors

You need to install the Leiningen build tool to build the library. You can get it here: Leiningen

The library uses the Apache POI library which will be downloaded by the "lein deps" command.

Then build the library:

 lein deps
 lein compile
 lein test

To run the tests on all supported Clojure versions use:

lein all test

To check for security issues use:

lein nvd check

To check for new versions of dependencies:

lein ancient

Build Status

Build Status

License

Copyright (c) 2009-2020 Martin Jul

Docjure is licensed under the MIT License. See the LICENSE file for the license terms.

Docjure uses the Apache POI library, which is licensed under the Apache License v2.0.

For more information on Apache POI refer to the Apache POI web site.

Contact information

Martin Jul

Contributors

This library includes great contributions from

Thank you very much!

Honorary Mention

A special thank you also goes out to people that did not contribute code but shared their ideas, reported security issues or bugs and otherwise inspired the continuing work on the project.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].