diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -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.
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,2 @@
+import Distribution.Simple
+main = defaultMain
diff --git a/src/Codec/Xlsx/Util/Tabular.hs b/src/Codec/Xlsx/Util/Tabular.hs
new file mode 100644
--- /dev/null
+++ b/src/Codec/Xlsx/Util/Tabular.hs
@@ -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)
diff --git a/src/Codec/Xlsx/Util/Tabular/Imports.hs b/src/Codec/Xlsx/Util/Tabular/Imports.hs
new file mode 100644
--- /dev/null
+++ b/src/Codec/Xlsx/Util/Tabular/Imports.hs
@@ -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
+                     )
diff --git a/src/Codec/Xlsx/Util/Tabular/Json.hs b/src/Codec/Xlsx/Util/Tabular/Json.hs
new file mode 100644
--- /dev/null
+++ b/src/Codec/Xlsx/Util/Tabular/Json.hs
@@ -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
diff --git a/src/Codec/Xlsx/Util/Tabular/Types.hs b/src/Codec/Xlsx/Util/Tabular/Types.hs
new file mode 100644
--- /dev/null
+++ b/src/Codec/Xlsx/Util/Tabular/Types.hs
@@ -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 ""
diff --git a/test/Spec.hs b/test/Spec.hs
new file mode 100644
--- /dev/null
+++ b/test/Spec.hs
@@ -0,0 +1,2 @@
+main :: IO ()
+main = putStrLn "Test suite not yet implemented"
diff --git a/xlsx-tabular.cabal b/xlsx-tabular.cabal
new file mode 100644
--- /dev/null
+++ b/xlsx-tabular.cabal
@@ -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
