2011-04-18 8 views
7

के साथ OpenXml का उपयोग करके शीट को जोड़ने में असमर्थ OpenXml दस्तावेज़ से CreateSpreadsheetWorkbook उदाहरण विधि सीधे F # पर अनुवाद करती है। समस्या शीट ऑब्जेक्ट की संलग्न विधि प्रतीत होती है। कोड त्रुटि के बिना निष्पादित करता है, लेकिन परिणामस्वरूप xlsx फ़ाइल में आंतरिक एक्सएमएल गुम होती है जिसे जोड़ा जाना चाहिए था, और फ़ाइल एक्सेल द्वारा अपठनीय है। मुझे संदेह है कि समस्या कार्यात्मक एफ # संरचनाओं को एक सिस्टम में परिवर्तित करने से उत्पन्न होती है। चयन प्रकार, लेकिन मेरे पास इसके लिए प्रत्यक्ष सबूत नहीं हैं।F # (FSharp)

मैंने सी # और वीबी.नेट (यानी प्रलेखन उदाहरण) में समान कोड चलाया है और यह पूरी तरह निष्पादित करता है और एक पठनीय, पूर्ण xlsx फ़ाइल बनाता है।

मुझे पता है कि मैं सीधे एक्सएमएल से निपट सकता हूं, लेकिन मैं एफ # और ओपनएक्सएमएल के बीच विसंगति की प्रकृति को समझना चाहता हूं। कोई सुझाव?

कोड उदाहरण से लगभग सीधे है:

namespace OpenXmlLib 
open System 
open DocumentFormat 
open DocumentFormat.OpenXml 
open DocumentFormat.OpenXml.Packaging 
open DocumentFormat.OpenXml.Spreadsheet 

module OpenXmlXL = 
    // this function overwrites an existing file without warning! 
    let CreateSpreadsheetWorkbook (filepath: string) = 
     // Create a spreadsheet document by supplying the filepath. 
     // By default, AutoSave = true, Editable = true, and Type = xlsx. 
     let spreadsheetDocument = SpreadsheetDocument.Create(filepath, SpreadsheetDocumentType.Workbook) 
     // Add a WorkbookPart to the document. 
     let workbookpart = spreadsheetDocument.AddWorkbookPart() 
     workbookpart.Workbook <- new Workbook() 

     // Add a WorksheetPart to the WorkbookPart. 
     let worksheetPart = workbookpart.AddNewPart<WorksheetPart>() 
     worksheetPart.Worksheet <- new Worksheet(new SheetData()) 

     // Add Sheets to the Workbook. 
     let sheets = spreadsheetDocument.WorkbookPart.Workbook.AppendChild<Sheets>(new Sheets()) 

     // Append a new worksheet and associate it with the workbook. 
     let sheet = new Sheet() 
     sheet.Id <- stringValue(spreadsheetDocument.WorkbookPart.GetIdOfPart(worksheetPart)) 
     //Console.WriteLine(sheet.Id.Value) 

     sheet.SheetId <- UInt32Value(1u) 
     // Console.WriteLine(sheet.SheetId.Value) 

     sheet.Name <- StringValue("TestSheet") 
     //Console.WriteLine(sheet.Name.Value) 


     sheets.Append (sheet) 

    // Console.WriteLine("Sheets: {0}", sheets.InnerXml.ToString()) 

     workbookpart.Workbook.Save() 


     spreadsheetDocument.Close() 

शीट बनाई गई है, लेकिन खाली:

sheet.xml:

<?xml version="1.0" encoding="utf-8" ?> 
    <x:worksheet xmlns:x="http://schemas.openxmlformats.org/spreadsheetml/2006/main" /> 

workbook.xml: 
    <?xml version="1.0" encoding="utf-8" ?> 
- <x:workbook xmlns:x="http://schemas.openxmlformats.org/spreadsheetml/2006/main"> 
- <x:sheets> 
    <x:sheet name="TestSheet" sheetId="1" r:id="R263eb6f245a2497e" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" /> 
    </x:sheets> 
    </x:workbook> 
+1

आप अपने कोड पोस्ट कर सकते हैं:

इसे ठीक करने के लिए आप इतना है कि वे अन्य अधिभार (नीचे पहला उदाहरण) का उपयोग अपने कॉल की स्थापना या स्पष्ट रूप से एक सिंगलटन अनुक्रम (नीचे दूसरे उदाहरण) बनाने की जरूरत ? जब आप इसे अनजिप करते हैं तो xlsx में वास्तव में क्या होता है? शीट बनाई गई है लेकिन खाली है? क्या इसमें कोई रिफ्रेंस जोड़ा गया है? – Nobody

+2

ऐसा लगता है कि आप इस एमएसडीएन पृष्ठ से उदाहरण कोड का उपयोग कर रहे हैं: http://msdn.microsoft.com/en-us/library/ff478153.aspx। मुझे सच में संदेह है कि यह एफ # के साथ एक समस्या है - आपका कोड सही दिखता है, लेकिन आपको एमएसडीएन पर एक गलत उदाहरण मिल सकता है। देखें कि क्या आप सी # प्रोजेक्ट में उदाहरण कोड वर्बैटिम का उपयोग कर सकते हैं, क्या आपको अलग-अलग परिणाम मिलते हैं? – Juliet

+0

केवीबी के लिए धन्यवाद। कलाकार ने काम किया। मैंने शीट्स और शीट ऑब्जेक्ट पर यह कोशिश की थी, लेकिन यह मेरे लिए कभी नहीं हुआ कि शीटडाटा ऑब्जेक्ट पर संदेह था। एक बार फिर धन्यवाद। –

उत्तर

16

समस्या, बहुत सूक्ष्म है और Worksheet कन्स्ट्रक्टर और Sheets.Append विधि पर आपकी कॉल में है। इन दोनों विधियों को अधिभारित किया गया है, और या तो seq<OpenXmlElement> या व्यक्तिगत OpenXmlElement एस ([<System.ParamArray>]/params सरणी के माध्यम से) ले सकते हैं। मोड़ यह है कि OpenXmlElement प्रकार स्वयं seq<OpenXmlElement> इंटरफ़ेस लागू करता है।

सी # में, जब आप new Worksheet(new SheetData()) पर कॉल करते हैं, तो कंपाइलर का ओवरलोड रिज़ॉल्यूशन ओवरलोड के दूसरे को चुनता है, जो कि SheetData मान वाले एक-तत्व सरणी को स्पष्ट रूप से बनाता है। हालांकि, एफ # में, SheetData वर्ग IEnumerable<OpenXmlElement> लागू करता है, पहला अधिभार चुना जाता है, जो की सामग्री की गणना करके एक नया WorkSheet बनाता है, जो आप नहीं चाहते हैं।

worksheetPart.Worksheet <- new Worksheet(new SheetData() :> OpenXmlElement) 
... 
sheets.Append([sheet :> OpenXmlElement]) 
+1

+1: ओह वाह जो अस्पष्ट है :) – Juliet

+1

+1: धन्यवाद। यह वास्तव में मेरी मदद करता है, मैं दस्तावेज़ Format.OpenXml के लिए एमएसडीएन पर उदाहरण का पालन कर रहा था और बस यह नहीं देख सका कि क्या गलत था! – Goody