无法使用 OpenXml 在 F# 中读取 Excel 文件

Unable to read from Excel file in F# using OpenXml

我想知道如何使用 F# 从现有的 Excel 文件中读取数据。 我发现了这个(相当老的)问题,但有问题 运行 它:

似乎编译器或 SDK(或两者)都针对这一行进行了更改:

let theSheet:Worksheet = ((WorksheetPart.wbPart.GetPartById(firstSheet.Id)).Worksheet

(我知道括号有错字,只是想引用原文)

即使没有额外的括号和以下代码:

// Learn more about F# at http://fsharp.org

open System
open System.Linq
open System.Data
open System.Windows
open DocumentFormat.OpenXml // Also install DocumentFormat.OpenXml from nuget
open DocumentFormat.OpenXml.Packaging
open DocumentFormat.OpenXml.Spreadsheet
open Microsoft.Office.Interop.Excel

let toStr s = Printf.TextWriterFormat<unit>(s)

//Read the value of a single cell by string coordinates (Open XML SDK)
let read_value_openxml (file_path_and_name:string) (column:int) (row:int):string =
    let stream = new System.IO.FileStream(file_path_and_name, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.ReadWrite)

    // Open the spreadsheet document for read-only access.
    let document = SpreadsheetDocument.Open(stream, false)

    // Retrieve a reference to the workbook part.
    let wbPart = document.WorkbookPart

    // Find the sheet with the supplied name, and then use that sheet object to retrieve a reference to the first worksheet.
    let firstSheet:Sheet = wbPart.Workbook.Descendants<Sheet>().Where(fun s -> (toStr s.Name.Value).Equals("Sheet1")).First()


    // Retrieve a reference to the worksheet part.
    let wsPart:Worksheet = wbPart.GetPartById(firstSheet.Id.ToString())

    // Use its Worksheet property to get a reference to the cell whose address matches the address you supplied.
    let theCell = wsPart.Worksheet.Descendants<Cell>().Where(fun c -> c.CellReference = column + row).FirstOrDefault()

    "test"

编译器抱怨该行

let wsPart:Worksheet = wbPart.GetPartById(firstSheet.Id.ToString())

这么说

Severity    Code    Description Project File    Line    Suppression State
Error   FS0001  This expression was expected to have type
    'Worksheet'    
but here has type
    'OpenXmlPart'   HelloF  C:\Users\user\Documents\workspace\FSharp\HelloF\HelloF\Program.fs   32  Active

我也试图像这样显式地将值从 OpenXmlPart 转换为 Worksheet

let ws:Worksheet = (wbPart.GetPartById(firstSheet.Id.ToString()):OpenXmlPart) :?> Worksheet

虽然结果相同。

所以我查了一下问题 in the SDK Documentation, which provided the following example code (in VB):

...
' Reference to Excel Worksheet with Customer data. 
custID = _
   workSheets.First(Function(sheet) sheet.Name = "Customer").Id()
aacustSheet = DirectCast( _
   document.WorkbookPart.GetPartById(custID), WorksheetPart)

这部分代码使用DirectCast

在 F# 中使用此 SDK 的正确方法是什么? 我找到了几个关于如何通过创建新的 WorkBookParts 创建新的 Excel 文件的示例,但不幸的是没有仅供阅读的工作示例。

您可以为此使用 EPPlus。这是一个非常简单的脚本示例:

#r @"C:\Users\flavi\.nuget\packages\epplus.0.4\lib\net45\EPPlus.dll"

open OfficeOpenXml
open System.IO

let sheetFile = new FileInfo(@"C:\somefolder\someExcelFile.xlsx")
let sheetName = "SomeSheet"

using (new ExcelPackage(sheetFile)) (fun p ->
    let wk = p.Workbook                     //the workbook
    let ws = wk.Worksheets.[sheetName]      //a worksheet
    let someCell = ws.Cells.[1,1]           //a single cell
    printfn "%A" someCell.Value)

然后您可以探索其他方法和属性来完成任务。

您是否考虑过 Excel 类型的提供商?

https://fsprojects.github.io/ExcelProvider/