xlsx

2018-07-11

Basic reader for Excel files.

Upstream URL

gitlab.common-lisp.net/cungil/xlsx

Author

Carlos Ungil <ungil@mac.com>

License

MIT
README
;; example: creating a sqlite database from an excel sheet ;; (the contents of the first row are used as column names) (asdf:load-system :sqlite) (asdf:load-system :xlsx) (defun fix-name (str) (loop for char in '(#\- #\/ #\Space) do (setf str (substitute #\_ char str))) (setf str (remove #\. str)) (if (digit-char-p (elt str 0)) (concatenate 'string "_" str) str)) (defun xlsx-to-sqlite (file &optional (na "_NA_")) (let ((xlsx (probe-file file))) (when (null xlsx) (error "~A not found" file)) (let ((sqlite (merge-pathnames (make-pathname :type "sqlite") xlsx))) (when (probe-file sqlite) (error "~A exists already" sqlite)) (let* ((data (xlsx:as-matrix (xlsx:read-sheet file 1) na)) (fields (loop for col from 0 below (array-dimension data 1) collect (fix-name (aref data 0 col)))) (numeric (loop for col from 0 below (array-dimension data 1) collect (every (lambda (x) (or (numberp x) (null x))) (loop for row from 1 below (array-dimension data 0) collect (aref data row col))))) (create-sql (format nil "CREATE TABLE data(~{~A~^,~})" (loop for f in fields for n in numeric collect (if n (format nil "~A NUMBER" f) f)))) (insert-sql (format nil "INSERT INTO data VALUES (~{~A~^,~})" (loop repeat (length fields) collect "?")))) (sqlite:with-open-database (db sqlite) (sqlite:execute-to-list db create-sql) (loop for row from 1 below (array-dimension data 0) do (apply #'sqlite:execute-non-query db insert-sql (loop for col from 0 below (length fields) for item = (aref data row col) collect (if (equal item na) nil item)))))))))

Dependencies (3)

  • flexi-streams
  • xmls
  • zip

Dependents (0)

    • GitHub
    • Quicklisp