Skip to content

Commit

Permalink
First cut at using the ExcelDataReader library
Browse files Browse the repository at this point in the history
  • Loading branch information
JohnDoeKyrgyz committed Jun 14, 2013
1 parent 0947db5 commit fa899bd
Show file tree
Hide file tree
Showing 16 changed files with 153 additions and 39 deletions.
3 changes: 3 additions & 0 deletions FSharpx.TypeProviders.Tests.sln.DotSettings
@@ -0,0 +1,3 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/FilterSettingsManager/CoverageFilterXml/@EntryValue">&lt;data&gt;&lt;IncludeFilters /&gt;&lt;ExcludeFilters /&gt;&lt;/data&gt;</s:String>
<s:String x:Key="/Default/FilterSettingsManager/AttributeFilterXml/@EntryValue">&lt;data /&gt;</s:String></wpf:ResourceDictionary>
3 changes: 3 additions & 0 deletions FSharpx.WithTypeProviders.sln.DotSettings
@@ -0,0 +1,3 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/FilterSettingsManager/CoverageFilterXml/@EntryValue">&lt;data&gt;&lt;IncludeFilters /&gt;&lt;ExcludeFilters /&gt;&lt;/data&gt;</s:String>
<s:String x:Key="/Default/FilterSettingsManager/AttributeFilterXml/@EntryValue">&lt;data /&gt;</s:String></wpf:ResourceDictionary>
22 changes: 22 additions & 0 deletions packages/ExcelDataReader.2.1.1/ExcelDataReader.2.1.1.nuspec
@@ -0,0 +1,22 @@
<?xml version="1.0"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>ExcelDataReader</id>
<version>2.1.1</version>
<title>ExcelDataReader</title>
<authors>iciobanu</authors>
<owners>iciobanu</owners>
<projectUrl>http://exceldatareader.codeplex.com/</projectUrl>
<iconUrl>https://nugetgallery.blob.core.windows.net/icons/ExcelDataReader.2.1.png</iconUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>Lightweight and fast library written in C# for reading Microsoft Excel files ('97-2007).</description>
<summary>Lightweight and fast library written in C# for reading Microsoft Excel files ('97-2007).</summary>
<releaseNotes />
<copyright />
<language />
<tags>Excel</tags>
<dependencies>
<dependency id="SharpZipLib" version="0.86.0" />
</dependencies>
</metadata>
</package>
10 changes: 10 additions & 0 deletions packages/ExcelDataReader.2.1.1/content/app.config.transform
@@ -0,0 +1,10 @@
<configuration>
<runtime>
<assemblyBinding>
<dependentAssembly>
<assemblyIdentity name="ICSharpCode.SharpZipLib" publicKeyToken="1b03e6acf1164f73" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-0.86.0.518" newVersion="0.86.0.518" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
10 changes: 10 additions & 0 deletions packages/ExcelDataReader.2.1.1/content/web.config.transform
@@ -0,0 +1,10 @@
<configuration>
<runtime>
<assemblyBinding>
<dependentAssembly>
<assemblyIdentity name="ICSharpCode.SharpZipLib" publicKeyToken="1b03e6acf1164f73" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-0.86.0.518" newVersion="0.86.0.518" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
Binary file not shown.
Binary file not shown.
14 changes: 14 additions & 0 deletions packages/SharpZipLib.0.86.0/SharpZipLib.0.86.0.nuspec
@@ -0,0 +1,14 @@
<?xml version="1.0"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>SharpZipLib</id>
<version>0.86.0</version>
<title>SharpZipLib</title>
<authors>http://www.icsharpcode.net/</authors>
<owners>http://www.icsharpcode.net/</owners>
<projectUrl>http://www.icsharpcode.net/OpenSource/SharpZipLib/Default.aspx</projectUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>#ziplib (SharpZipLib, formerly NZipLib) is a Zip, GZip, Tar and BZip2 library written entirely in C# for the .NET platform. It is implemented as an assembly (installable in the GAC), and thus can easily be incorporated into other projects (in any .NET language).</description>
<summary>#ziplib (SharpZipLib, formerly NZipLib) is a Zip, GZip, Tar and BZip2 library written entirely in C# for the .NET platform. It is implemented as an assembly (installable in the GAC), and thus can easily be incorporated into other projects (in any .NET language).</summary>
</metadata>
</package>
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
1 change: 1 addition & 0 deletions packages/repositories.config
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<repositories>
<repository path="..\src\FSharpx.TypeProviders.Excel\packages.config" />
<repository path="..\tests\FSharpx.CSharpTests\packages.config" />
<repository path="..\tests\FSharpx.DataStructures.Tests\packages.config" />
<repository path="..\tests\FSharpx.Http.Tests\packages.config" />
Expand Down
113 changes: 74 additions & 39 deletions src/FSharpx.TypeProviders.Excel/ExcelProvider.fs
Expand Up @@ -4,50 +4,90 @@ open System.IO
open System
open Samples.FSharp.ProvidedTypes
open Microsoft.FSharp.Core.CompilerServices
open Microsoft.Office.Interop
open FSharpx.TypeProviders.Helper
open System.Collections.Generic

let ApplyMoveToRange (rg:Excel.Range) (move:Excel.XlDirection) = rg.Worksheet.Range(rg, rg.End(move))

let internal getRange (xlWorkBookInput : Excel.Workbook) sheetorrangename (headerRow : int) =
let mysheets = seq { for sheet in xlWorkBookInput.Worksheets do yield sheet :?> Excel.Worksheet }
let names = seq { for name in xlWorkBookInput.Names do yield name :?> Excel.Name}
let hasWs = Seq.exists (fun (ws:Excel.Worksheet) -> (ws.Name = sheetorrangename)) mysheets
if hasWs then
let sheet = Seq.find (fun (ws:Excel.Worksheet) -> (ws.Name = sheetorrangename)) mysheets
let firstcell = sheet.Cells.Item(box headerRow, 1) :?> Excel.Range
ApplyMoveToRange (ApplyMoveToRange firstcell Excel.XlDirection.xlToRight) Excel.XlDirection.xlDown
open System.Data
open System
open Excel

let parseExcelAddress cellAddress =

let convertToBase radix digits =
let digitValue i digit = float digit * Math.Pow(float radix, float i)

digits
|> List.rev
|> List.mapi digitValue
|> Seq.sum
|> int

let charToDigit char = ((int)(Char.ToUpper(char))) - 64

let column =
cellAddress
|> Seq.filter Char.IsLetter
|> Seq.map charToDigit
|> Seq.toList
|> convertToBase 26

let row =
cellAddress
|> Seq.filter Char.IsNumber
|> Seq.map (string >> Int32.Parse)
|> Seq.toList
|> convertToBase 10

(row - 1), (column - 1)

let internal getCells (workbook : DataSet) sheetOrRangeName headerRowIndex =
let worksheets = workbook.Tables

//if sheetOrRangeName refers to a worksheet get the header row from the specified worksheet
if worksheets.Contains(sheetOrRangeName) then
let sheet = worksheets.[sheetOrRangeName]

//remove unecessary leading rows
if headerRowIndex > 0 then do
for row in 0 .. headerRowIndex do
let removeRow = sheet.Rows.[headerRowIndex]
sheet.Rows.Remove(removeRow);
sheet
else
let hasName = Seq.exists (fun (ws:Excel.Name) -> (ws.Name = sheetorrangename)) names
if hasName then
(Seq.find (fun (ws:Excel.Name) -> (ws.Name = sheetorrangename)) names ).RefersToRange
let sheet = worksheets.[0]
let topLeft = 0, 0
let bottomRight =
if sheetOrRangeName.Contains(":") then
let addresses = sheetOrRangeName.Split(':');
let topLeft = parseExcelAddress addresses.[0]
let bottomRight = parseExcelAddress addresses.[1]


else
failwith (sprintf "Sheet or range %A was not found" sheetorrangename)


else
failwith (sprintf "Sheet or range %A was not found" sheetOrRangeName)

// Simple type wrapping Excel data
type ExcelFileInternal(filename, sheetorrangename, headerRow : int) =
let data =
let xlApp = new Excel.ApplicationClass()
xlApp.Visible <- false
xlApp.ScreenUpdating <- false
xlApp.DisplayAlerts <- false;
let xlWorkBookInput = xlApp.Workbooks.Open(filename)

let xlRangeInput = getRange xlWorkBookInput sheetorrangename headerRow
let data =
use stream = File.OpenRead(filename)
let excelReader =
if filename.EndsWith(".xlsx") then ExcelReaderFactory.CreateOpenXmlReader(stream)
else ExcelReaderFactory.CreateBinaryReader(stream)

let objRangeInput = xlRangeInput.Value2 :?> obj[,]
let res = seq { for irow in 2 .. objRangeInput.GetLength(0) do
yield seq { for jcol in 1 .. objRangeInput.GetLength(1) do
yield objRangeInput.[irow,jcol] }
|> Seq.toArray }
|> Seq.toArray
let workbook = excelReader.AsDataSet()
let data = getCells workbook sheetorrangename headerRow

xlWorkBookInput.Close()
xlApp.Quit()
res
let res = seq { for irow in 2 .. data.Rows.Count do
yield seq { for jcol in 1 .. data.Columns.Count do
yield data.Rows.[irow].[jcol] }
|> Seq.toArray }
|> Seq.toArray
res

member __.Data = data
member __.Data = data

type internal ReflectiveBuilder =
static member Cast<'a> (args:obj) =
Expand Down Expand Up @@ -102,9 +142,7 @@ let internal typExcel(cfg:TypeProviderConfig) =
let resolvedFilename = Path.Combine(cfg.ResolutionFolder, filename)

let ProvidedTypeDefinitionExcelCall (filename, sheetorrangename, forcestring, headerRow) =
let xlApp = new Excel.ApplicationClass()
let xlWorkBookInput = xlApp.Workbooks.Open(resolvedFilename)


let xlRangeInput = getRange xlWorkBookInput sheetorrangename headerRow

let lines = (seq { for row in xlRangeInput.Rows do yield row } |> Seq.cache)
Expand Down Expand Up @@ -142,9 +180,6 @@ let internal typExcel(cfg:TypeProviderConfig) =
prop.AddDefinitionLocation(1, i, filename)
rowTy.AddMember(prop)

xlWorkBookInput.Close()
xlApp.Quit()

// define the provided type, erasing to excelFile
let ty = ProvidedTypeDefinition(System.Reflection.Assembly.GetExecutingAssembly(), rootNamespace, tyName, Some(typeof<ExcelFileInternal>))

Expand Down
11 changes: 11 additions & 0 deletions src/FSharpx.TypeProviders.Excel/app.config
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<assemblyBinding>
<dependentAssembly>
<assemblyIdentity name="ICSharpCode.SharpZipLib" publicKeyToken="1b03e6acf1164f73" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-0.86.0.518" newVersion="0.86.0.518" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>
5 changes: 5 additions & 0 deletions src/FSharpx.TypeProviders.Excel/packages.config
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="ExcelDataReader" version="2.1.1" targetFramework="net40" />
<package id="SharpZipLib" version="0.86.0" targetFramework="net40" />
</packages>

0 comments on commit fa899bd

Please sign in to comment.