packages feed

xlsx-tabular (empty) → 0.1.0.0

raw patch · 8 files changed

+415/−0 lines, 8 filesdep +aesondep +basedep +bytestringsetup-changed

Dependencies added: aeson, base, bytestring, containers, data-default, lens, text, xlsx, xlsx-tabular

Files

+ LICENSE view
@@ -0,0 +1,30 @@+Copyright Kazuo Koga (c) 2016++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 Kazuo Koga 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.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ src/Codec/Xlsx/Util/Tabular.hs view
@@ -0,0 +1,184 @@+{-# LANGUAGE FlexibleContexts  #-}+{-# LANGUAGE LambdaCase        #-}+{-# LANGUAGE OverloadedStrings #-}+-- | Convinience utility to read Xlsx tabular cells.+module Codec.Xlsx.Util.Tabular+       (+         -- * Types+         Tabular+       , TabularHead+       , TabularRow+         -- * Lenses+         -- ** Tabular+       , tabularHeads+       , tabularRows+         -- ** TabularHead+       , tabularHeadIx+       , tabularHeadLabel+         -- ** TabularRow+       , tabularRowIx+       , tabularRowCells+         -- * Methods+       , def+         -- * Functions+       , toTableRowsFromFile+       , toTableRows+       , toTableRows'+       ) where++import Codec.Xlsx.Util.Tabular.Imports+import qualified Data.ByteString.Lazy as ByteString++type Rows =+  [(Int, Cols)]++type Cols =+  [(Int, Cell)]++type RowValues =+  [(Int, [(Int, Maybe CellValue)])]+++-- |Read from Xlsx file as tabular rows+toTableRowsFromFile :: Int -- ^ Starting row index (header row)+                    -> String -- ^ File name+                    -> IO (Maybe Tabular)+toTableRowsFromFile offset fname = do+  s <- ByteString.readFile fname+  let xlsx = toXlsx s+      rows = toTableRows' xlsx offset+  pure rows++-- |Decode cells as tabular rows.+toTableRows :: Xlsx -- ^ Xlsx Workbook+            -> Text -- ^ Worksheet name to decode+            -> Int -- ^ Starting row index (header row)+            -> Maybe Tabular+toTableRows xlsx sheetName offset =+  decodeRows <$> styles <*> Just offset <*> rows+  where+    styles = parseStyleSheet (xlsx ^. xlStyles) ^? _Right+    rows =+      xlsx+      ^? ixSheet sheetName+      . wsCells+      . to toRows++-- |Decode cells as tabular rows from first sheet.+toTableRows' :: Xlsx -- ^ Xlsx Workbook+             -> Int -- ^ Starting row index (header row)+             -> Maybe Tabular+toTableRows' xlsx offset =+  toTableRows xlsx firstSheetName offset+  where+    firstSheetName =+      xlsx ^. xlSheets+      & keys+      & head++decodeRows ss offset rs =+  def+  & tabularHeads .~ header'+  & tabularRows .~ rows+  where+    rs' = getCells ss offset rs+    header = head rs' ^. _2+    header' =+      header+      & fmap toText+      & join+    toText (i, Just (CellText t)) = [def+                                     & tabularHeadIx .~ i+                                     & tabularHeadLabel .~ t]+    toText _ = []+    cix = fmap (view tabularHeadIx) header'+      & fromList+    rows =+      fmap rowValue (tail rs')+    rowValue rvs =+      def+      & tabularRowIx .~ (rvs ^. _1)+      & tabularRowCells .~ (rvs ^. _2 & fmap f & join)+      where+        f (i, cell) =+          [cell | cix ^. contains i]++-- |行から値のあるセルを取り出す+getCells :: StyleSheet -- ^スタイルシート+         -> Int -- ^開始行+         -> Rows -- ^セル行+         -> RowValues+getCells ss i rs =+  startAt ss i rs+  & takeContiguous i+  & takeUntil ss+  & fmap rvs+  & filter vs+  where+    rvs (i, cs) =+      (i, rowValues cs)+    filter =+      Prelude.filter+    vs (i, cs) =+      any (\(_, v) -> isJust v) cs++startAt :: StyleSheet -> Int -> Rows -> Rows+startAt ss i rs =+  dropWhile f rs+  where+    f (x, _) =+      x < i++-- |指定の行から連続している行を取り出す+takeContiguous :: Int -> Rows -> Rows+takeContiguous i rs =+  [r | (x, r@(y, _)) <- zip [i..] rs, x == y]++-- |有効セルのすべてに枠線(Bottom側)が存在しなくなる+-- |すなわち枠囲みの欄外になるまでの行を取り出す+takeUntil :: StyleSheet -> Rows -> Rows+takeUntil ss rs =+  takeWhile f rs+  where+    f (i, cs) =+      or $ rowBordersHas borderBottom ss cs++rowBordersHas v ss cs =+  x+  where+    x =+      fmap f cs+    f (i, cell) =+      cellHasBorder ss cell v++rowValues cs =+  x+  where+    x =+      fmap f cs+    f (i, cell) =+      (i, cell ^. cellValue)++cellHasBorder ss cell v =+  fromMaybe False mb+  where+    b = cellBorder ss cell+    mb = borderStyleHasLine v <$> b++cellBorder :: StyleSheet -> Cell -> Maybe Border+cellBorder ss cell =+  view cellStyle cell+  >>= pure . xf+  >>= view cellXfBorderId+  >>= pure . bd+  where+    xf n = (ss ^. styleSheetCellXfs) !! n+    bd n = (ss ^. styleSheetBorders) !! n++borderStyleHasLine v b =+  fromMaybe False value+  where+  value =+    view v b+    >>= view borderStyleLine+    >>= pure . (/= LineStyleNone)
+ src/Codec/Xlsx/Util/Tabular/Imports.hs view
@@ -0,0 +1,52 @@+-- |Internal imports.+module Codec.Xlsx.Util.Tabular.Imports+       ( module X+       , join+       , find+       , fromMaybe+       , isJust+       , keys+       , (<$>), (<*>)+       , view+       , to+       , contains+       , (^.), (^?), (.~), (?~), (&), _1, _2, _Right+       , Text+       , IntSet+       , IntSet.fromList+       , FromJSON, parseJSON+       , ToJSON, toJSON+       , Value(Object), object+       , (.=), (.:)+       , deriveJSON+       , defaultOptions+       , fieldLabelModifier+       , constructorTagModifier+       )+       where++import Codec.Xlsx as X+import Codec.Xlsx.Formatted as X+import Codec.Xlsx.Util.Tabular.Types as X+import Control.Applicative ((<$>), (<*>))+import Control.Lens ( (^.), (^?), (.~), (?~), (&)+                    , _1, _2, _Right+                    , view, to, contains+                    )+import Control.Monad (join)+import Data.List (find)+import Data.Map (keys)+import Data.Maybe (fromMaybe, isJust)+import Data.Text (Text)+import Data.IntSet (IntSet)+import qualified Data.IntSet as IntSet+import Data.Aeson ( FromJSON, parseJSON+                  , ToJSON, toJSON+                  , Value(Object), object+                  , (.=), (.:)+                  )+import Data.Aeson.TH ( deriveJSON+                     , defaultOptions+                     , fieldLabelModifier+                     , constructorTagModifier+                     )
+ src/Codec/Xlsx/Util/Tabular/Json.hs view
@@ -0,0 +1,43 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE TemplateHaskell   #-}+-- | JSON supports of Tabular.+module Codec.Xlsx.Util.Tabular.Json+       ( parseJSON+       , toJSON+       ) where++import Codec.Xlsx.Util.Tabular.Imports+import Data.Char (toLower)+++instance ToJSON RichTextRun where+  toJSON r =+    object [ "text" .= view richTextRunText r ]++instance FromJSON RichTextRun where+  parseJSON (Object v) =+    RichTextRun <$> pure Nothing <*> (v .: "text")+++deriveJSON defaultOptions+  { fieldLabelModifier = drop 5+  , constructorTagModifier = map toLower . drop 4+  } ''CellValue+++deriveJSON defaultOptions+  { fieldLabelModifier = map toLower . drop 11+  , constructorTagModifier = map toLower+  } ''TabularRow+++deriveJSON defaultOptions+  { fieldLabelModifier = map toLower . drop 12+  , constructorTagModifier = map toLower+  } ''TabularHead+++deriveJSON defaultOptions+  { fieldLabelModifier = map toLower . drop 8+  , constructorTagModifier = map toLower+  } ''Tabular
+ src/Codec/Xlsx/Util/Tabular/Types.hs view
@@ -0,0 +1,59 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE TemplateHaskell   #-}++module Codec.Xlsx.Util.Tabular.Types+       ( Tabular+       , tabularHeads+       , tabularRows+       , TabularHead+       , tabularHeadIx+       , tabularHeadLabel+       , TabularRow+       , tabularRowIx+       , tabularRowCells+       , def+       ) where++import Codec.Xlsx (CellValue)+import Control.Lens (makeLenses)+import Data.Default (Default, def)+import Data.Text (Text)+++-- | Tabular cells+data Tabular = Tabular+  { _tabularHeads :: [TabularHead]+  , _tabularRows :: [TabularRow]+  }+  deriving (Show)++-- | Tabular header+data TabularHead = TabularHead+  { _tabularHeadIx :: Int -- ^ Column index+  , _tabularHeadLabel :: Text -- ^ Column label+  }+  deriving (Show)++-- | Tabular row+data TabularRow = TabularRow+  { _tabularRowIx :: Int -- ^ Row index+  , _tabularRowCells :: [Maybe CellValue] -- ^ Row values+  }+  deriving (Show)+++makeLenses ''Tabular+makeLenses ''TabularHead+makeLenses ''TabularRow+++instance Default Tabular where+  def = Tabular [] []+++instance Default TabularRow where+  def = TabularRow 0 []+++instance Default TabularHead where+  def = TabularHead 0 ""
+ test/Spec.hs view
@@ -0,0 +1,2 @@+main :: IO ()+main = putStrLn "Test suite not yet implemented"
+ xlsx-tabular.cabal view
@@ -0,0 +1,43 @@+name:                xlsx-tabular+version:             0.1.0.0+synopsis:            Xlsx table decode utility+description:         Please see README.md+homepage:            http://github.com/kkazuo/xlsx-tabular#readme+license:             BSD3+license-file:        LICENSE+author:              Kazuo Koga+maintainer:          obiwanko@me.com+copyright:           (c) 2016 Kazuo Koga+category:            Codec+build-type:          Simple+-- extra-source-files:+cabal-version:       >=1.10++library+  hs-source-dirs:      src+  exposed-modules:     Codec.Xlsx.Util.Tabular+                     , Codec.Xlsx.Util.Tabular.Types+                     , Codec.Xlsx.Util.Tabular.Imports+                     , Codec.Xlsx.Util.Tabular.Json+  build-depends:       base >= 4.7 && < 5+                     , aeson+                     , bytestring+                     , containers+                     , data-default+                     , lens+                     , text+                     , xlsx+  default-language:    Haskell2010++test-suite xlsx-tabular-test+  type:                exitcode-stdio-1.0+  hs-source-dirs:      test+  main-is:             Spec.hs+  build-depends:       base+                     , xlsx-tabular+  ghc-options:         -threaded -rtsopts -with-rtsopts=-N+  default-language:    Haskell2010++source-repository head+  type:     git+  location: https://github.com/kkazuo/xlsx-tabular