packages feed

HExcel (empty) → 0.1.0.0

raw patch · 13 files changed

+1321/−0 lines, 13 filesdep +basedep +microlensdep +microlens-thsetup-changedbinary-added

Dependencies added: base, microlens, microlens-th, time, transformers

Files

+ .DS_Store view

binary file changed (absent → 6148 bytes)

+ ._.DS_Store view

binary file changed (absent → 120 bytes)

+ CHANGELOG.md view
@@ -0,0 +1,5 @@+# Revision history for HExcel++## 0.1.0.0 -- YYYY-mm-dd++* First version. Released on an unsuspecting world.
+ HExcel.cabal view
@@ -0,0 +1,40 @@+cabal-version: 1.12++-- This file has been generated from package.yaml by hpack version 0.31.2.+--+-- see: https://github.com/sol/hpack+--+-- hash: 62133125a83cd855af0e3dd872fb71b2de059d93bef1b7f5504ad003a4115eb7++name:           HExcel+version:        0.1.0.0+synopsis:       Create Excel files with Haskell+description:    Easily create Excel files with Haskell. See README at <https://github.com/green-lambda/HExcel>+category:       Data, Text, SpreadSheet+author:         Sasha Bogicevic+maintainer:     sasa.bogicevic@pm.me+license:        BSD3+license-file:   LICENSE+build-type:     Simple++library+  exposed-modules:+      HExcel+  other-modules:+      HExcel.Ffi+      HExcel.HExcelInternal+      HExcel.Types+      Paths_HExcel+  hs-source-dirs:+      src+  ghc-options: -Wall+  extra-libraries:+      z+      xlsxwriter+  build-depends:+      base >=4.5 && <4.13+    , microlens+    , microlens-th+    , time+    , transformers+  default-language: Haskell2010
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2019, Sasa Bogicevic++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above+      copyright notice, this list of conditions and the following+      disclaimer in the documentation and/or other materials provided+      with the distribution.++    * Neither the name of Sasa Bogicevic nor the names of other+      contributors may be used to endorse or promote products derived+      from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ README.md view
@@ -0,0 +1,53 @@+# HExcel+Create Excel files with Haskell+-------------------------------------------------------------------------------+This is a fork of [libxlsxwriter](https://github.com/HalfWayMan/libxlsxwriter)+that tries the improve on the api and provide a library for+creation of Excel files.+Underneath the hood it uses C library called [libxlsxwriter](http://libxlsxwriter.github.io/) and provides+bindings to C code to produce Excel 2007+ xlsx files.++## Example++```+{-# LANGUAGE TypeApplications #-}+module Main where++import Control.Monad.Trans.State (execStateT)+import Control.Monad (forM_)+import Data.Time (getZonedTime)+import HExcel++main :: IO ()+main = do+  wb <- workbookNew "test.xlsx"+  let props = mkDocProperties+        { docPropertiesTitle   = "Test Workbook"+        , docPropertiesCompany = "HExcel"+        }+  workbookSetProperties wb props+  ws <- workbookAddWorksheet wb "First Sheet"+  df <- workbookAddFormat wb+  formatSetNumFormat df "mmm d yyyy hh:mm AM/PM"+  now <- getZonedTime+  -- You can create HExcelState which is convenient api for writing to cells +  let initState = HExcelState Nothing ws 4 1 0 1 0+  _ <- flip execStateT initState $ do+         writeCell "David"+         writeCell "Dimitrije"+		 -- we can skip some rows+         skipRows 1+         writeCell "Jovana"+		 -- or skip some columns+         skipCols 1+         writeCell (zonedTimeToDateTime now)+         writeCell @Double 42.5++  -- or use functions that run in plain IO+  forM_ [5 .. 8] $ \n -> do+    writeString ws Nothing n 3 "xxx"+    writeNumber ws Nothing n 4 1234.56+    writeDateTime ws (Just df) n 5 (zonedTimeToDateTime now)+  workbookClose wb++```
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ package.yaml view
@@ -0,0 +1,27 @@+name:       HExcel+version:    0.1.0.0+synopsis:   Create Excel files with Haskell+author:     Sasha Bogicevic+maintainer: sasa.bogicevic@pm.me+license:    BSD3+build-type: Simple+description: Easily create Excel files with Haskell. See README at <https://github.com/green-lambda/HExcel>+category: Data, Text, SpreadSheet++dependencies:+  - base >= 4.5 && < 4.13+  - transformers+  - time+  - microlens+  - microlens-th++ghc-options: -Wall++library:+  exposed-modules:+    - HExcel+  source-dirs:+    - src+  extra-libraries:+    - z+    - xlsxwriter
+ src/HExcel.hs view
@@ -0,0 +1,55 @@+-- |+-- Module      :  HExcel+-- Maintainer  :  Sasha Bogicevic <sasa.bogicevic@pm.me>+-- Stability   :  experimental+--+-- Module exports+--+-- Example usage:+--+-- > {-# LANGUAGE TypeApplications #-}+-- > module Main where+-- >+-- > import Control.Monad.Trans.State (execStateT)+-- > import Control.Monad (forM_)+-- > import Data.Time (getZonedTime)+-- > import HExcel+-- >+-- > main :: IO ()+-- > main = do+-- >   wb <- workbookNew "test.xlsx"+-- >   let props = mkDocProperties+-- >         { docPropertiesTitle   = "Test Workbook"+-- >         , docPropertiesCompany = "HExcel"+-- >         }+-- >   workbookSetProperties wb props+-- >   ws <- workbookAddWorksheet wb "First Sheet"+-- >   df <- workbookAddFormat wb+-- >   formatSetNumFormat df "mmm d yyyy hh:mm AM/PM"+-- >   now <- getZonedTime+-- >   -- You can create HExcelState which is convenient api for writing to cells+-- >   let initState = HExcelState Nothing ws 4 1 0 1 0+-- >   _ <- flip execStateT initState $ do+-- >          writeCell "David"+-- >          writeCell "Dimitrije"+-- >          -- we can skip some rows+-- >          skipRows 1+-- >          writeCell "Jovana"+-- >          -- skip some columns+-- >          skipCols 1+-- >          writeCell (zonedTimeToDateTime now)+-- >          writeCell @Double 42.5+-- >+-- >   -- or use functions that run in plain IO+-- >   forM_ [5 .. 8] $ \n -> do+-- >     writeString ws Nothing n 3 "xxx"+-- >     writeNumber ws Nothing n 4 1234.56+-- >     writeDateTime ws (Just df) n 5 (zonedTimeToDateTime now)+-- >   workbookClose wb++module HExcel+  ( module HExcel.HExcelInternal+  )+  where++import HExcel.HExcelInternal
+ src/HExcel/Ffi.hs view
@@ -0,0 +1,209 @@+{-# LANGUAGE ForeignFunctionInterface #-}++-- |+-- Module      :  HExcel.Ffi+-- Maintainer  :  Sasha Bogicevic <sasa.bogicevic@pm.me>+-- Stability   :  experimental+--+-- FFI code++module HExcel.Ffi where++import Foreign+import Foreign.C.String+import HExcel.Types++foreign import ccall "workbook_new"+  workbook_new :: CString -> IO (Ptr LxwWorkbook_)++foreign import ccall "workbook_new_opt"+  workbook_new_opt :: CString -> Ptr WorkbookOptions -> IO (Ptr LxwWorkbook_)++foreign import ccall "workbook_close"+  workbook_close :: Ptr LxwWorkbook_ -> IO ()++foreign import ccall "workbook_add_worksheet"+  workbook_add_worksheet :: Ptr LxwWorkbook_ -> CString ->+                            IO (Ptr LxwWorksheet_)++foreign import ccall "workbook_add_format"+  workbook_add_format :: Ptr LxwWorkbook_ -> IO (Ptr LxwFormat_)++foreign import ccall "workbook_set_properties"+  workbook_set_properties :: Ptr LxwWorkbook_ ->+                             Ptr DocProperties' -> IO ()++foreign import ccall "workbook_define_name"+  workbook_define_name :: Ptr LxwWorkbook_ -> CString -> CString -> IO ()++foreign import ccall "worksheet_write_number"+  worksheet_write_number :: Ptr LxwWorksheet_ ->+                            Word32 -> Word16 ->+                            Double -> Ptr LxwFormat_ -> IO ()++foreign import ccall "worksheet_write_string"+  worksheet_write_string :: Ptr LxwWorksheet_ ->+                            Word32 -> Word16 ->+                            CString -> Ptr LxwFormat_ -> IO ()++foreign import ccall "worksheet_write_formula"+  worksheet_write_formula :: Ptr LxwWorksheet_ ->+                             Word32 -> Word16 ->+                             CString -> Ptr LxwFormat_ -> IO ()++foreign import ccall "worksheet_write_array_formula"+  worksheet_write_array_formula :: Ptr LxwWorksheet_ ->+                                   Word32 -> Word16 ->+                                   Word32 -> Word16 ->+                                   CString -> Ptr LxwFormat_ -> IO ()++foreign import ccall "worksheet_write_datetime"+  worksheet_write_datetime :: Ptr LxwWorksheet_ ->+                              Word32 -> Word16 ->+                              Ptr DateTime -> Ptr LxwFormat_ -> IO ()++foreign import ccall "worksheet_write_url"+  worksheet_write_url :: Ptr LxwWorksheet_ ->+                         Word32 -> Word16 ->+                         CString -> Ptr LxwFormat_ -> IO ()++foreign import ccall "worksheet_set_row"+  worksheet_set_row :: Ptr LxwWorksheet_ ->+                       Word32 -> Double -> Ptr LxwFormat_ -> IO ()++foreign import ccall "worksheet_set_column"+  worksheet_set_column :: Ptr LxwWorksheet_ ->+                          Word16 -> Word16 -> Double -> Ptr LxwFormat_ -> IO ()++foreign import ccall "worksheet_insert_image"+  worksheet_insert_image :: Ptr LxwWorksheet_ ->+                            Word32 -> Word16 -> CString -> IO ()++foreign import ccall "worksheet_insert_image_opt"+  worksheet_insert_image_opt :: Ptr LxwWorksheet_ ->+                                Word32 -> Word16 ->+                                CString -> Ptr ImageOptions -> IO ()++foreign import ccall "worksheet_merge_range"+  worksheet_merge_range :: Ptr LxwWorksheet_ ->+                           Word32 -> Word16 ->+                           Word32 -> Word16 ->+                           CString -> Ptr LxwFormat_ -> IO ()++foreign import ccall "worksheet_freeze_panes"+  worksheet_freeze_panes :: Ptr LxwWorksheet_ ->+                            Word32 -> Word16 -> IO ()++foreign import ccall "worksheet_split_panes"+  worksheet_split_panes :: Ptr LxwWorksheet_ ->+                           Double -> Double -> IO ()++foreign import ccall "worksheet_set_landscape"+  worksheet_set_landscape :: Ptr LxwWorksheet_ -> IO ()++foreign import ccall "worksheet_set_portrait"+  worksheet_set_portrait :: Ptr LxwWorksheet_ -> IO ()++foreign import ccall "worksheet_set_page_view"+  worksheet_set_page_view :: Ptr LxwWorksheet_ -> IO ()++foreign import ccall "worksheet_set_paper"+  worksheet_set_paper :: Ptr LxwWorksheet_ -> Word8 -> IO ()++foreign import ccall "worksheet_set_margins"+  worksheet_set_margins :: Ptr LxwWorksheet_ ->+                           Double -> Double ->+                           Double -> Double -> IO ()++foreign import ccall "worksheet_set_header"+  worksheet_set_header :: Ptr LxwWorksheet_ -> CString -> IO ()++foreign import ccall "worksheet_set_footer"+  worksheet_set_footer :: Ptr LxwWorksheet_ -> CString -> IO ()++foreign import ccall "worksheet_set_zoom"+  worksheet_set_zoom :: Ptr LxwWorksheet_ -> Word16 -> IO ()++foreign import ccall "worksheet_set_print_scale"+  worksheet_set_print_scale:: Ptr LxwWorksheet_ -> Word16 -> IO ()++foreign import ccall "format_set_font_name"+  format_set_font_name :: Ptr LxwFormat_ -> CString -> IO ()++foreign import ccall "format_set_font_size"+  format_set_font_size :: Ptr LxwFormat_ -> Word16 -> IO ()++foreign import ccall "format_set_font_color"+  format_set_font_color :: Ptr LxwFormat_ -> Int32 -> IO ()++foreign import ccall "format_set_num_format"+  format_set_num_format :: Ptr LxwFormat_ -> CString -> IO ()++foreign import ccall "format_set_bold"+  format_set_bold :: Ptr LxwFormat_ -> IO ()++foreign import ccall "format_set_italic"+  format_set_italic :: Ptr LxwFormat_ -> IO ()++foreign import ccall "format_set_underline"+  format_set_underline :: Ptr LxwFormat_ -> Word8 -> IO ()++foreign import ccall "format_set_font_strikeout"+  format_set_font_strikeout :: Ptr LxwFormat_ -> IO ()++foreign import ccall "format_set_font_script"+  format_set_font_script :: Ptr LxwFormat_ -> Word8 -> IO ()++foreign import ccall "format_set_num_format_index"+  format_set_num_format_index :: Ptr LxwFormat_ -> Word8 -> IO ()++foreign import ccall "format_set_align"+  format_set_align :: Ptr LxwFormat_ -> Word8 -> IO ()++foreign import ccall "format_set_text_wrap"+  format_set_text_wrap :: Ptr LxwFormat_ -> IO ()++foreign import ccall "format_set_rotation"+  format_set_rotation :: Ptr LxwFormat_ -> Int16 -> IO ()++foreign import ccall "format_set_shrink"+  format_set_shrink :: Ptr LxwFormat_ -> IO ()++foreign import ccall "format_set_pattern"+  format_set_pattern :: Ptr LxwFormat_ -> Word8 -> IO ()++foreign import ccall "format_set_bg_color"+  format_set_bg_color :: Ptr LxwFormat_ -> Int32 -> IO ()++foreign import ccall "format_set_fg_color"+  format_set_fg_color :: Ptr LxwFormat_ -> Int32 -> IO ()++foreign import ccall "format_set_border"+  format_set_border :: Ptr LxwFormat_ -> Word8 -> IO ()++foreign import ccall "format_set_bottom"+  format_set_bottom :: Ptr LxwFormat_ -> Word8 -> IO ()++foreign import ccall "format_set_top"+  format_set_top :: Ptr LxwFormat_ -> Word8 -> IO ()++foreign import ccall "format_set_left"+  format_set_left :: Ptr LxwFormat_ -> Word8 -> IO ()++foreign import ccall "format_set_right"+  format_set_right :: Ptr LxwFormat_ -> Word8 -> IO ()++foreign import ccall "format_set_border_color"+  format_set_border_color :: Ptr LxwFormat_ -> Int32 -> IO ()++foreign import ccall "format_set_bottom_color"+  format_set_bottom_color :: Ptr LxwFormat_ -> Int32 -> IO ()++foreign import ccall "format_set_top_color"+  format_set_top_color :: Ptr LxwFormat_ -> Int32 -> IO ()++foreign import ccall "format_set_left_color"+  format_set_left_color :: Ptr LxwFormat_ -> Int32 -> IO ()++foreign import ccall "format_set_right_color"+  format_set_right_color :: Ptr LxwFormat_ -> Int32 -> IO ()
+ src/HExcel/HExcelInternal.hs view
@@ -0,0 +1,604 @@+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE InstanceSigs      #-}+{-# LANGUAGE RecordWildCards   #-}++-- |+-- Module      :  HExcel.HExcelInternal+-- Maintainer  :  Sasha Bogicevic <sasa.bogicevic@pm.me>+-- Stability   :  experimental+--+-- This module contains almost all of the library functionality.++module HExcel.HExcelInternal+  ( Workbook+  , workbookNew+  , workbookNewConstantMem+  , workbookClose+  , workbookAddWorksheet+  , workbookAddFormat+  , workbookDefineName+  , DocProperties (..)+  , workbookSetProperties+  , Worksheet+  , Row+  , Col+  , writeNumber+  , writeString+  , writeUTCTime+  , writeFormula+  , writeArrayFormula+  , DateTime (..)+  , utcTimeToDateTime+  , zonedTimeToDateTime+  , writeDateTime+  , writeUrl+  , worksheetSetRow+  , worksheetSetColumn+  , ImageOptions (..)+  , worksheetInsertImage+  , worksheetInsertImageOpt+  , worksheetMergeRange+  , worksheetFreezePanes+  , worksheetSplitPanes+  , worksheetSetLandscape+  , worksheetSetPortrait+  , worksheetSetPageView+  , PaperSize (..)+  , skipCols+  , skipRows+  , worksheetSetPaperSize+  , worksheetSetMargins+  , worksheetSetHeaderCtl+  , worksheetSetFooterCtl+  , worksheetSetZoom+  , worksheetSetPrintScale+  , Format+  , formatSetFontName+  , formatSetFontSize+  , Color (..)+  , formatSetFontColor+  , formatSetNumFormat+  , formatSetBold+  , formatSetItalic+  , UnderlineStyle (..)+  , formatSetUnderline+  , formatSetStrikeout+  , ScriptStyle (..)+  , formatSetScript+  , formatSetBuiltInFormat+  , Align (..)+  , VerticalAlign (..)+  , formatSetAlign+  , formatSetVerticalAlign+  , formatSetTextWrap+  , formatSetRotation+  , formatSetShrink+  , Pattern (..)+  , formatSetPattern+  , formatSetBackgroundColor+  , formatSetForegroundColor+  , Border (..)+  , BorderStyle (..)+  , formatSetBorder+  , formatSetBorderColor+  , HExcelState (..)+  , HExcel (..)+  , mkDocProperties+  ) where++import Control.Monad.IO.Class+import Control.Monad.Trans.State+import Data.Time+import Data.Time.Clock.POSIX+import Foreign+import Foreign.C.String+import Foreign.C.Types+import HExcel.Ffi+import HExcel.Types+import Lens.Micro++-- | HExcel class that provides a single function `writeCell` as a convenient method+-- of writing excel cell values+class HExcel a where+  writeCell :: MonadIO m => a -> StateT HExcelState m ()++instance HExcel String where+  writeCell :: MonadIO m => String -> StateT HExcelState m ()+  writeCell val = do+    s@HExcelState {..} <- get+    liftIO $+      writeString+        _hexcelStateSheet+        _hexcelStateFormat+        _hexcelStateRow+        _hexcelStateCol+        val+    put $ modifyRowColState s++instance HExcel UTCTime where+  writeCell :: MonadIO m => UTCTime -> StateT HExcelState m ()+  writeCell val = do+    s@HExcelState {..} <- get+    liftIO $+      writeUTCTime+        _hexcelStateSheet+        _hexcelStateFormat+        _hexcelStateRow+        _hexcelStateCol+        val+    put $ modifyRowColState s++instance HExcel DateTime where+  writeCell :: MonadIO m => DateTime -> StateT HExcelState m ()+  writeCell val = do+    s@HExcelState {..} <- get+    liftIO $+      writeDateTime+        _hexcelStateSheet+        _hexcelStateFormat+        _hexcelStateRow+        _hexcelStateCol+        val+    put $ modifyRowColState s++instance HExcel Double where+  writeCell :: MonadIO m => Double -> StateT HExcelState m ()+  writeCell val = do+    s@HExcelState {..} <- get+    liftIO $+      writeNumber+        _hexcelStateSheet+        _hexcelStateFormat+        _hexcelStateRow+        _hexcelStateCol+        val+    put $ modifyRowColState s++instance HExcel Int where+  writeCell :: MonadIO m => Int -> StateT HExcelState m ()+  writeCell val = do+    s@HExcelState {..} <- get+    liftIO $+      writeNumber+        _hexcelStateSheet+        _hexcelStateFormat+        _hexcelStateRow+        _hexcelStateCol+        (fromIntegral val :: Double)+    put $ modifyRowColState s++instance HExcel Float where+  writeCell :: MonadIO m => Float -> StateT HExcelState m ()+  writeCell val = do+    s@HExcelState {..} <- get+    liftIO $+      writeNumber+        _hexcelStateSheet+        _hexcelStateFormat+        _hexcelStateRow+        _hexcelStateCol+        (realToFrac val :: Double)+    put $ modifyRowColState s++instance HExcel Integer where+  writeCell :: MonadIO m => Integer -> StateT HExcelState m ()+  writeCell val = do+    s@HExcelState {..} <- get+    liftIO $+      writeNumber+        _hexcelStateSheet+        _hexcelStateFormat+        _hexcelStateRow+        _hexcelStateCol+        (realToFrac val :: Double)+    put $ modifyRowColState s++instance HExcel Word where+  writeCell :: MonadIO m => Word -> StateT HExcelState m ()+  writeCell val = do+    s@HExcelState {..} <- get+    liftIO $+      writeNumber+        _hexcelStateSheet+        _hexcelStateFormat+        _hexcelStateRow+        _hexcelStateCol+        (realToFrac val :: Double)+    put $ modifyRowColState s++-- | Internal Helper function to change the state of row and column+modifyRowColState :: HExcelState -> HExcelState+modifyRowColState s@HExcelState {..} =+  if _hexcelStateRowCeiling == _hexcelStateRow+     then+       s & hexcelStateRow .~ _hexcelStateInitRow+         & hexcelStateCol +~ 1+     else+       s & hexcelStateRow +~ 1++-- | Skip a number of rows+skipRows :: MonadIO m => Word32 -> StateT HExcelState m ()+skipRows numberOfRows = do+  s@HExcelState {..} <- get+  put $ s & hexcelStateRow .~ _hexcelStateRow + numberOfRows++-- | Skip a number of columns+skipCols :: MonadIO m => Word16 -> StateT HExcelState m ()+skipCols numberOfCols = do+  s@HExcelState {..} <- get+  put $ s & hexcelStateCol .~ _hexcelStateCol + numberOfCols++-- | Create new workbook+workbookNew :: FilePath -> IO Workbook+workbookNew path = withCString path $ fmap Workbook . workbook_new++-- | Create new workbook but force constant memory.+-- It reduces the amount of data stored in memory so that large files+-- can be written efficiently.+workbookNewConstantMem :: FilePath -> IO Workbook+workbookNewConstantMem path =+  with (WorkbookOptions True) $ \copts ->+    withCString path $ \cpath ->+      Workbook <$> workbook_new_opt cpath copts++-- | Close the workbook+workbookClose :: Workbook -> IO ()+workbookClose (Workbook wb) =+  workbook_close wb++-- | Add the worksheet+workbookAddWorksheet :: Workbook -> String -> IO Worksheet+workbookAddWorksheet (Workbook wb) name =+  withCString name $ fmap Worksheet . workbook_add_worksheet wb++-- | Add workbook format+workbookAddFormat :: Workbook -> IO Format+workbookAddFormat (Workbook wb) =+  Format <$> workbook_add_format wb++withDocProperties :: DocProperties -> (Ptr DocProperties' -> IO a) -> IO a+withDocProperties props action =+  withCString (docPropertiesTitle props) $ \ctitle ->+  withCString (docPropertiesSubject props) $ \csubject ->+  withCString (docPropertiesAuthor props) $ \cauthor ->+  withCString (docPropertiesManager props) $ \cmanager ->+  withCString (docPropertiesCompany props) $ \ccompany ->+  withCString (docPropertiesCategory props) $ \ccat ->+  withCString (docPropertiesKeywords props) $ \ckws ->+  withCString (docPropertiesComments props) $ \ccmts ->+  withCString (docPropertiesStatus props) $ \cstat ->+  withCString (docPropertiesHyperlinkBase props) $ \clb ->+    let time   = CTime (round (utcTimeToPOSIXSeconds (docPropertiesCreated props)))+        props' = DocProperties' ctitle csubject cauthor cmanager+                                ccompany ccat ckws ccmts cstat clb time+    in with props' action++-- | Set workbook properties+workbookSetProperties :: Workbook -> DocProperties -> IO ()+workbookSetProperties (Workbook wb) props =+  withDocProperties props $ \cprops ->+    workbook_set_properties wb cprops++-- | Set workbook name+workbookDefineName :: Workbook -> String -> String -> IO ()+workbookDefineName (Workbook wb) name formula =+  withCString name $ \cname -> withCString formula $ \cformula ->+    workbook_define_name wb cname cformula++-- | Write a 'Double' value to Excel cell+writeNumber :: Worksheet -> Maybe Format -> Row -> Col -> Double -> IO ()+writeNumber (Worksheet ws) mfmt row col number =+  worksheet_write_number ws row col number (maybe nullPtr unFormat mfmt)++-- | Write a 'String' value to Excel cell+writeString :: Worksheet -> Maybe Format -> Row -> Col -> String -> IO ()+writeString (Worksheet ws) mfmt row col str =+  withCString str $ \cstr ->+    worksheet_write_string ws row col cstr (maybe nullPtr unFormat mfmt)++-- | Write a 'UTCTime' value to Excel cell+writeUTCTime :: Worksheet -> Maybe Format -> Row -> Col -> UTCTime -> IO ()+writeUTCTime (Worksheet ws) mfmt row col t = do+    let tz = localTimeToUTC utc . utcToLocalTime (TimeZone 60 True "BST")+        ts = utcTimeToPOSIXSeconds (read "1900-01-01 00:00:00") - (2 * 24 * 60 * 60)+        ft = fromRational . toRational . (/ (24 * 60 * 60)) . (+ negate ts) . utcTimeToPOSIXSeconds . tz+    worksheet_write_number ws row col (ft t) (maybe nullPtr unFormat mfmt)++-- | Write a formula to Excel cell+writeFormula :: Worksheet -> Maybe Format -> Row -> Col -> String -> IO ()+writeFormula (Worksheet ws) mfmt row col str =+  withCString str $ \cstr ->+    worksheet_write_formula ws row col cstr (maybe nullPtr unFormat mfmt)++writeArrayFormula+  :: Worksheet+  -> Maybe Format+  -> Row+  -> Col+  -> Row+  -> Col+  -> String+  -> IO ()+writeArrayFormula (Worksheet ws) mfmt frow fcol erow ecol str =+  withCString str $ \cstr ->+    worksheet_write_array_formula+      ws+      frow+      fcol+      erow+      ecol+      cstr+      (maybe nullPtr unFormat mfmt)++-- | Helper function to convert  'UTCTime' to 'DateTime'+utcTimeToDateTime :: UTCTime -> DateTime+utcTimeToDateTime (UTCTime day time) =+  let (y, m, d)        = toGregorian day+      TimeOfDay h mi s = timeToTimeOfDay time+  in DateTime (fromIntegral y) (fromIntegral m) (fromIntegral d)+       (fromIntegral h) (fromIntegral mi) (fromRational (toRational s))++-- | Helper function to convert  'ZonedTime' to 'DateTime'+zonedTimeToDateTime :: ZonedTime -> DateTime+zonedTimeToDateTime = utcTimeToDateTime . zonedTimeToUTC++-- | Write a 'DateTime' to Excel cell+writeDateTime :: Worksheet -> Maybe Format -> Row -> Col -> DateTime -> IO ()+writeDateTime (Worksheet ws) mfmt row col dt =+  with dt $ \pdt ->+    worksheet_write_datetime ws row col pdt (maybe nullPtr unFormat mfmt)++-- | Write a url to Excel cell+writeUrl :: Worksheet -> Maybe Format -> Row -> Col -> String -> IO ()+writeUrl (Worksheet ws) mfmt row col str =+  withCString str $ \cstr ->+    worksheet_write_url ws row col cstr (maybe nullPtr unFormat mfmt)++-- | Set worksheet row+worksheetSetRow :: Worksheet -> Maybe Format -> Row -> Double -> IO ()+worksheetSetRow (Worksheet ws) mfmt row height =+  worksheet_set_row ws row height (maybe nullPtr unFormat mfmt)++-- | Set worksheet column+worksheetSetColumn :: Worksheet -> Maybe Format -> Col -> Col -> Double -> IO ()+worksheetSetColumn (Worksheet ws) mfmt fcol lcol width =+  worksheet_set_column ws fcol lcol width (maybe nullPtr unFormat mfmt)++-- | Insert image to worksheet+worksheetInsertImage :: Worksheet -> Word32 -> Word16 -> String -> IO ()+worksheetInsertImage (Worksheet ws) row col path =+  withCString path $ \cpath ->+    worksheet_insert_image ws row col cpath++worksheetInsertImageOpt+  :: Worksheet+  -> Row+  -> Col+  -> FilePath+  -> ImageOptions+  -> IO ()+worksheetInsertImageOpt (Worksheet ws) row col path opt =+  withCString path $ \cpath ->+    with opt $ \optr -> worksheet_insert_image_opt ws row col cpath optr++-- | Merge columns+worksheetMergeRange+  :: Worksheet+  -> Maybe Format+  -> Row+  -> Col+  -> Row+  -> Col+  -> String+  -> IO ()+worksheetMergeRange (Worksheet ws) mfmt frow fcol lrow lcol str =+  withCString str $ \cstr ->+    worksheet_merge_range+      ws+      frow+      fcol+      lrow+      lcol+      cstr+      (maybe nullPtr unFormat mfmt)++worksheetFreezePanes :: Worksheet -> Row -> Col -> IO ()+worksheetFreezePanes (Worksheet ws) = worksheet_freeze_panes ws++worksheetSplitPanes :: Worksheet -> Double -> Double -> IO ()+worksheetSplitPanes (Worksheet ws) = worksheet_split_panes ws++-- | Set worksheet to Landscape+worksheetSetLandscape :: Worksheet -> IO ()+worksheetSetLandscape (Worksheet ws) =+  worksheet_set_landscape ws++-- | Set worksheet to Portrait+worksheetSetPortrait :: Worksheet -> IO ()+worksheetSetPortrait (Worksheet ws) =+  worksheet_set_portrait ws++worksheetSetPageView :: Worksheet -> IO ()+worksheetSetPageView (Worksheet ws) =+  worksheet_set_page_view ws++-- | Set worksheet 'PaperSize'+worksheetSetPaperSize :: Worksheet -> PaperSize -> IO ()+worksheetSetPaperSize (Worksheet ws) paper =+  worksheet_set_paper ws (toPaper paper)+  where+    toPaper :: PaperSize -> Word8+    toPaper DefaultPaper   = 0+    toPaper LetterPaper    = 1+    toPaper A3Paper        = 8+    toPaper A4Paper        = 9+    toPaper A5Paper        = 11+    toPaper (OtherPaper n) = n++-- | Set worksheet margins+worksheetSetMargins :: Worksheet -> Double -> Double -> Double -> Double -> IO ()+worksheetSetMargins (Worksheet ws) = worksheet_set_margins ws++worksheetSetHeaderCtl :: Worksheet -> String -> IO ()+worksheetSetHeaderCtl (Worksheet ws) str =+  withCString str $ \cstr -> worksheet_set_header ws cstr++worksheetSetFooterCtl :: Worksheet -> String -> IO ()+worksheetSetFooterCtl (Worksheet ws) str =+  withCString str $ \cstr -> worksheet_set_footer ws cstr++worksheetSetZoom :: Worksheet -> Double -> IO ()+worksheetSetZoom (Worksheet ws) zoom =+  worksheet_set_zoom ws (round (100.0 * zoom'))+  where+    zoom' = min 0.1 (max 4.0 zoom)++worksheetSetPrintScale :: Worksheet -> Double -> IO ()+worksheetSetPrintScale (Worksheet ws) scale =+  worksheet_set_print_scale ws (round (100.0 * scale'))+  where+    scale' = min 0.1 (max 4.0 scale)++-- | Set font name+formatSetFontName :: Format -> String -> IO ()+formatSetFontName (Format fp) name =+  withCString name $ \cname ->+    format_set_font_name fp cname++-- | Set font size+formatSetFontSize :: Format -> Word16 -> IO ()+formatSetFontSize (Format fp) = format_set_font_size fp++colorIndex :: Color -> Int32+colorIndex ColorBlack    = 0x00000000+colorIndex ColorBlue     = 0x000000ff+colorIndex ColorBrown    = 0x00800000+colorIndex ColorCyan     = 0x0000ffff+colorIndex ColorGray     = 0x00808080+colorIndex ColorGreen    = 0x00008000+colorIndex ColorLime     = 0x0000ff00+colorIndex ColorMagenta  = 0x00ff00ff+colorIndex ColorNavy     = 0x00000080+colorIndex ColorOrange   = 0x00ff6600+colorIndex ColorPink     = 0x00ff00ff+colorIndex ColorPurple   = 0x00800080+colorIndex ColorRed      = 0x00ff0000+colorIndex ColorSilver   = 0x00c0c0c0+colorIndex ColorWhite    = 0x00ffffff+colorIndex ColorYellow   = 0x00ffff00+colorIndex (Color r g b) =+  fromIntegral r `shiftL` 16 .|.+  fromIntegral g `shiftL`  8 .|.+  fromIntegral b++-- | Set font color+formatSetFontColor :: Format -> Color -> IO ()+formatSetFontColor (Format fp) color =+  format_set_font_color fp (colorIndex color)++-- | Set number format+formatSetNumFormat :: Format -> String -> IO ()+formatSetNumFormat (Format fp) fmt =+  withCString fmt $ \cfmt ->+    format_set_num_format fp cfmt++-- | Set bold style+formatSetBold :: Format -> IO ()+formatSetBold (Format fp) =+  format_set_bold fp++-- | Set italic style+formatSetItalic :: Format -> IO ()+formatSetItalic (Format fp) =+  format_set_italic fp++-- | Set underline style+formatSetUnderline :: Format -> UnderlineStyle -> IO ()+formatSetUnderline (Format fp) us =+  format_set_underline fp (fromIntegral (fromEnum us))++formatSetStrikeout :: Format -> IO ()+formatSetStrikeout (Format fp) =+  format_set_font_strikeout fp++formatSetScript :: Format -> ScriptStyle -> IO ()+formatSetScript (Format fp) s =+  format_set_font_script fp (1 + fromIntegral (fromEnum s))++formatSetBuiltInFormat :: Format -> Word8 -> IO ()+formatSetBuiltInFormat (Format fp) = format_set_num_format_index fp++formatSetAlign :: Format -> Align -> IO ()+formatSetAlign (Format fp) a = format_set_align fp (fromIntegral (fromEnum a))++formatSetVerticalAlign :: Format -> VerticalAlign -> IO ()+formatSetVerticalAlign (Format fp) a =+  format_set_align fp a'+  where+    a' = case fromEnum a of+      0 -> 0+      n -> 7 + fromIntegral n++formatSetTextWrap :: Format -> IO ()+formatSetTextWrap (Format fp) =+  format_set_text_wrap fp++formatSetRotation :: Format -> Int -> IO ()+formatSetRotation (Format fp) angle =+  format_set_rotation fp (fromIntegral angle)++formatSetShrink :: Format -> IO ()+formatSetShrink (Format fp) =+  format_set_shrink fp+++formatSetPattern :: Format -> Pattern -> IO ()+formatSetPattern (Format fp) pat =+  format_set_pattern fp (fromIntegral (fromEnum pat))++formatSetBackgroundColor :: Format -> Color -> IO ()+formatSetBackgroundColor (Format fp) color =+  format_set_bg_color fp (colorIndex color)++formatSetForegroundColor :: Format -> Color -> IO ()+formatSetForegroundColor (Format fp) color =+  format_set_fg_color fp (colorIndex color)+++formatSetBorder :: Format -> Border -> BorderStyle -> IO ()+formatSetBorder (Format fp) border style =+  function fp (fromIntegral (fromEnum style))+  where+    function = case border of+      BorderAll    -> format_set_border+      BorderBottom -> format_set_bottom+      BorderTop    -> format_set_top+      BorderLeft   -> format_set_left+      BorderRight  -> format_set_right++formatSetBorderColor :: Format -> Border -> Color -> IO ()+formatSetBorderColor (Format fp) border color =+  function fp (colorIndex color)+  where+    function = case border of+      BorderAll    -> format_set_border_color+      BorderBottom -> format_set_bottom_color+      BorderTop    -> format_set_top_color+      BorderLeft   -> format_set_left_color+      BorderRight  -> format_set_right_color++mkDocProperties :: DocProperties+mkDocProperties =+  DocProperties { docPropertiesTitle = ""+                , docPropertiesSubject       = ""+                , docPropertiesAuthor        = ""+                , docPropertiesManager       = ""+                , docPropertiesCompany       = ""+                , docPropertiesCategory      = ""+                , docPropertiesKeywords      = ""+                , docPropertiesComments      = ""+                , docPropertiesStatus        = ""+                , docPropertiesHyperlinkBase = ""+                , docPropertiesCreated       =+                    read "1984-07-06 18:00:00 UTC"+                }
+ src/HExcel/Types.hs view
@@ -0,0 +1,292 @@+{-# LANGUAGE TemplateHaskell #-}++-- |+-- Module      :  HExcel.Types+-- Maintainer  :  Sasha Bogicevic <sasa.bogicevic@pm.me>+-- Stability   :  experimental+--+-- HExcel types are defined here+module HExcel.Types where++import Data.Time+import Data.Word+import Foreign+import Foreign.C.String+import Foreign.C.Types+import Lens.Micro.TH++-- | Excel Row+type Row = Word32+-- | Excel Column+type Col = Word16++-- | Pointer to Excel Workbook+data LxwWorkbook_+-- | Excel Workbook+newtype Workbook = Workbook (Ptr LxwWorkbook_)++data LxwWorksheet_+-- | Excel WorkSheet+newtype Worksheet = Worksheet (Ptr LxwWorksheet_)++-- | Pointer to Excel Format+data LxwFormat_+-- | Excel Format+newtype Format = Format { unFormat :: Ptr LxwFormat_ }++-- | 'HExcelState' is the state we thread trough for the writeCell function of the+-- HExcel typeclass. We are trying to create a convenient api for writing cell values+-- without too much hassle.+data HExcelState =+  HExcelState+    { _hexcelStateFormat     :: Maybe Format+      -- ^ define a formatting to be used on all cells+    , _hexcelStateSheet      :: Worksheet+      -- ^ define a worksheet to write to+    , _hexcelStateRowCeiling :: Word32+      -- ^ max row size+    , _hexcelStateInitRow    :: Row+      -- ^ first row to write to+    , _hexcelStateInitCol    :: Col+      -- ^ first column to write to+    , _hexcelStateRow        :: Row+      -- ^ current row+    , _hexcelStateCol        :: Col+      -- ^ current column+    }++makeLenses ''HExcelState++-- | Excel WorkBook Options+newtype WorkbookOptions =+  WorkbookOptions { workbookOptionsConstantMem :: Bool }++instance Storable WorkbookOptions where+  sizeOf _ = sizeOf (undefined :: Word8)+  alignment _ = alignment (undefined :: Int)+  peek ptr = do+    cm <- peekByteOff ptr 0 :: IO Word8+    return (WorkbookOptions (cm /= 1))+  poke ptr opts = do+    let cm | workbookOptionsConstantMem opts = 1+           | otherwise = 0+    pokeByteOff ptr 0 (cm :: Word8)++-- | Colors+data Color+  = ColorBlack+  | ColorBlue+  | ColorBrown+  | ColorCyan+  | ColorGray+  | ColorGreen+  | ColorLime+  | ColorMagenta+  | ColorNavy+  | ColorOrange+  | ColorPink+  | ColorPurple+  | ColorRed+  | ColorSilver+  | ColorWhite+  | ColorYellow+  | Color Word8 Word8 Word8++-- | Underline styles+data UnderlineStyle+  = UnderlineNone+  | UnderlineSingle+  | UnderlineDouble+  | UnderlineSingleAccounting+  | UnderlineDoubleAccounting+  deriving (Eq, Enum, Read, Show)++-- | Script styles+data ScriptStyle+  = SuperScript+  | SubScript+  deriving (Eq, Enum, Read, Show)++-- | Alignment styles+data Align+  = AlignNone+  | AlignLeft+  | AlignCenter+  | AlignRight+  | AlignFill+  | AlignJustify+  | AlignCenterAcross+  | AlignDistributed+  deriving (Eq, Enum, Read, Show)++-- | Vertical align styles+data VerticalAlign+  = VerticalAlignNone+  | VerticalAlignTop+  | VerticalAlignBottom+  | VerticalAlignCenter+  | VerticalAlignJustify+  | VerticalAlignDistributed+  deriving (Eq, Enum, Read, Show)++-- | Pattern styles+data Pattern+  = PatternNone+  | PatternSolid+  | PatternMediumGray+  | PatternDarkGray+  | PatternLightGray+  | PatternDarkHorizontal+  | PatternDarkVertical+  | PatternDarkDown+  | PatternDarkUp+  | PatternDarkGrid+  | PatternDarkTrellis+  | PatternLightHorizontal+  | PatternLightVertical+  | PatternLightDown+  | PatternLightUp+  | PatternLightGrid+  | PatternLightTrellis+  | PatternGray125+  | PatternGray0625+  deriving (Eq, Enum, Read, Show)++-- | Border options+data Border+  = BorderAll+  | BorderBottom+  | BorderTop+  | BorderLeft+  | BorderRight+  deriving (Eq, Read, Show)++-- | Border styles+data BorderStyle+  = BorderNone+  | BorderThin+  | BorderMedium+  | BorderDashed+  | BorderDotted+  | BorderThick+  | BorderDouble+  | BorderHair+  | BorderMediumDashed+  | BorderDashDot+  | BorderMediumDashDot+  | BorderDashDotDot+  | BorderMediumDashDotDot+  | BorderSlantDashDot+  deriving (Eq, Enum, Read, Show)++-- | Excel document properties+data DocProperties =+  DocProperties { docPropertiesTitle         :: String+                , docPropertiesSubject       :: String+                , docPropertiesAuthor        :: String+                , docPropertiesManager       :: String+                , docPropertiesCompany       :: String+                , docPropertiesCategory      :: String+                , docPropertiesKeywords      :: String+                , docPropertiesComments      :: String+                , docPropertiesStatus        :: String+                , docPropertiesHyperlinkBase :: String+                , docPropertiesCreated       :: UTCTime {-CTime-}+               }++data DocProperties' =+  DocProperties' { docPropsTitle         :: CString+                 , docPropsSubject       :: CString+                 , docPropsAuthor        :: CString+                 , docPropsManager       :: CString+                 , docPropsCompany       :: CString+                 , docPropsCategory      :: CString+                 , docPropsKeywords      :: CString+                 , docPropsComments      :: CString+                 , docPropsStatus        :: CString+                 , docPropsHyperlinkBase :: CString+                 , docPropsCreated       :: CTime+                 }++instance Storable DocProperties' where+  sizeOf _ = 10 * sizeOf (undefined :: CString) ++                  sizeOf (undefined :: CTime)+  alignment _ = alignment (undefined :: CString)+  peek = error "No implementation of 'peek' for 'DocProperties'"+  poke ptr props = do+    let n = sizeOf (undefined :: CString)+    pokeByteOff ptr (0 * n) (docPropsTitle props)+    pokeByteOff ptr (1 * n) (docPropsSubject props)+    pokeByteOff ptr (2 * n) (docPropsAuthor props)+    pokeByteOff ptr (3 * n) (docPropsManager props)+    pokeByteOff ptr (4 * n) (docPropsCompany props)+    pokeByteOff ptr (5 * n) (docPropsCategory props)+    pokeByteOff ptr (6 * n) (docPropsKeywords props)+    pokeByteOff ptr (7 * n) (docPropsComments props)+    pokeByteOff ptr (8 * n) (docPropsStatus props)+    pokeByteOff ptr (9 * n) (docPropsHyperlinkBase props)+    pokeByteOff ptr (10 * n) (docPropsCreated props)++-- | Type to hold datetime values+data DateTime =+  DateTime { dtYear   :: CInt+           , dtMonth  :: CInt+           , dtDay    :: CInt+           , dtHour   :: CInt+           , dtMinute :: CInt+           , dtSecond :: CDouble+           }+  deriving (Show)++instance Storable DateTime where+  sizeOf _ = 5 * sizeOf (undefined :: Int) ++                 sizeOf (undefined :: Double)+  alignment _ = alignment (undefined :: Int)+  peek ptr = do+    let ptr' = castPtr ptr+    DateTime <$> peekElemOff ptr' 0+             <*> peekElemOff ptr' 1+             <*> peekElemOff ptr' 2+             <*> peekElemOff ptr' 3+             <*> peekElemOff ptr' 4+             <*> peekElemOff ptr' 5+  poke ptr (DateTime y m d h mi s) = do+    pokeByteOff ptr 0 y+    pokeByteOff ptr 4 m+    pokeByteOff ptr 8 d+    pokeByteOff ptr 12 h+    pokeByteOff ptr 16 mi+    pokeByteOff ptr 20 s++-- | Type to hold image options+data ImageOptions =+  ImageOptions { imageOffsetX :: Int32+               , imageOffsetY :: Int32+               , imageScaleX  :: Double+               , imageScaleY  :: Double+               }++instance Storable ImageOptions where+  sizeOf _ = 2 * sizeOf (undefined :: Int32) ++             2 * sizeOf (undefined :: Double)+  alignment _ = alignment (undefined :: Int32)+  peek ptr =+    ImageOptions <$> peekByteOff ptr 0+                 <*> peekByteOff ptr 4+                 <*> peekByteOff ptr 8+                 <*> peekByteOff ptr 16+  poke ptr (ImageOptions ox oy sx sy) = do+    pokeByteOff ptr 0 ox+    pokeByteOff ptr 4 oy+    pokeByteOff ptr 8 sx+    pokeByteOff ptr 16 sy++-- | Paper size+data PaperSize+  = DefaultPaper+  | LetterPaper+  | A3Paper+  | A4Paper+  | A5Paper+  | OtherPaper Word8+  deriving (Eq)
+ stack.yaml view
@@ -0,0 +1,4 @@+resolver: lts-13.26++packages:+- .