[c#] باستخدام Excel OleDb للحصول على أسماء الأوراق IN SHEET ORDER


Answers

لا يمكنك فقط حلقة من خلال ورقة من 0 إلى عدد من الأسماء -1؟ بهذه الطريقة يجب عليك الحصول عليها بالترتيب الصحيح.

تصحيح

لقد لاحظت من خلال التعليقات أن هناك الكثير من المخاوف حول استخدام فئات Interop لاسترداد أسماء الورقة. لذلك هنا مثال على استخدام OLEDB لاستردادها:

/// <summary>
/// This method retrieves the excel sheet names from 
/// an excel workbook.
/// </summary>
/// <param name="excelFile">The excel file.</param>
/// <returns>String[]</returns>
private String[] GetExcelSheetNames(string excelFile)
{
    OleDbConnection objConn = null;
    System.Data.DataTable dt = null;

    try
    {
        // Connection String. Change the excel file to the file you
        // will search.
        String connString = "Provider=Microsoft.Jet.OLEDB.4.0;" + 
          "Data Source=" + excelFile + ";Extended Properties=Excel 8.0;";
        // Create connection object by using the preceding connection string.
        objConn = new OleDbConnection(connString);
        // Open connection with the database.
        objConn.Open();
        // Get the data table containg the schema guid.
        dt = objConn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);

        if(dt == null)
        {
           return null;
        }

        String[] excelSheets = new String[dt.Rows.Count];
        int i = 0;

        // Add the sheet name to the string array.
        foreach(DataRow row in dt.Rows)
        {
           excelSheets[i] = row["TABLE_NAME"].ToString();
           i++;
        }

        // Loop through all of the sheets if you want too...
        for(int j=0; j < excelSheets.Length; j++)
        {
            // Query each excel sheet.
        }

        return excelSheets;
   }
   catch(Exception ex)
   {
       return null;
   }
   finally
   {
      // Clean up.
      if(objConn != null)
      {
          objConn.Close();
          objConn.Dispose();
      }
      if(dt != null)
      {
          dt.Dispose();
      }
   }
}

مستخرج من Article على CodeProject.

Question

أنا أستخدم OleDb للقراءة من مصنف Excel مع العديد من الأوراق.

أحتاج إلى قراءة أسماء الورقات ، لكنني أحتاج إليها بالترتيب المحدد في جدول البيانات ؛ إذا كان لدي ملف يشبه هذا ؛

|_____|_____|____|____|____|____|____|____|____|
|_____|_____|____|____|____|____|____|____|____|
|_____|_____|____|____|____|____|____|____|____|
\__GERMANY__/\__UK__/\__IRELAND__/

ثم أحتاج إلى الحصول على القاموس

1="GERMANY", 
2="UK", 
3="IRELAND"

لقد حاولت استخدام OleDbConnection.GetOleDbSchemaTable() ، وهذا يعطيني قائمة الأسماء ، ولكن فرزها حسب الترتيب الأبجدي. يعني alpha-sort أنني لا أعرف أي رقم ورقة يتوافق مع اسم معين. لذا فهمت

GERMANY, IRELAND, UK

التي غيرت ترتيب UK IRELAND .

السبب في حاجتي لفرزها هو أنه علي أن أسمح للمستخدم باختيار نطاق من البيانات حسب الاسم أو الفهرس. يمكنهم طلب "جميع البيانات من ألمانيا إلى أيرلندا" أو "البيانات من الورقة 1 إلى الورقة 3".

اي افكار يمكن ان تكون رائعه للعرض.

إذا كان بإمكاني استخدام الطبقات المتداخلة للمكتب ، فسيكون هذا الأمر واضحًا. لسوء الحظ ، لا أستطيع بسبب عدم عمل الصفوف المتداخلة بشكل يعتمد عليه في بيئات غير تفاعلية مثل خدمات Windows ومواقع ASP.NET ، لذا احتجت إلى استخدام OLEDB.




تعجبني فكرةdeathApril لتسمية الأوراق كـ 1_Germany ، 2_UK ، 3_IRELAND. لقد حصلت أيضًا على مشكلتك لإجراء هذا إعادة تسمية لمئات الأوراق. إذا لم تكن لديك مشكلة في إعادة تسمية اسم الورقة ، فيمكنك استخدام هذا الماكرو للقيام بذلك نيابةً عنك. سوف يستغرق أقل من ثانية لإعادة تسمية كافة أسماء الورقة. للأسف ODBC ، OLEDB بإرجاع ترتيب اسم الورقة بواسطة تصاعدي. لا يوجد بديل لذلك. يجب عليك استخدام COM أو إعادة تسمية اسمك في الترتيب.

Sub Macro1()
'
' Macro1 Macro
'

'
Dim i As Integer
For i = 1 To Sheets.Count
 Dim prefix As String
 prefix = i
 If Len(prefix) < 4 Then
  prefix = "000"
 ElseIf Len(prefix) < 3 Then
  prefix = "00"
 ElseIf Len(prefix) < 2 Then
  prefix = "0"
 End If
 Dim sheetName As String
 sheetName = Sheets(i).Name
 Dim names
 names = Split(sheetName, "-")
 If (UBound(names) > 0) And IsNumeric(names(0)) Then
  'do nothing
 Else
  Sheets(i).Name = prefix & i & "-" & Sheets(i).Name
 End If
Next

End Sub

استكمال: بعد قراءة التعليقSidHoland بشأن BIFF تومض فكرة. يمكن القيام بالخطوات التالية من خلال التعليمات البرمجية. لا أعرف ما إذا كنت تريد فعلًا ذلك للحصول على أسماء الورقات بنفس الترتيب. يُرجى إعلامي إذا كنت بحاجة إلى مساعدة للقيام بذلك من خلال الشفرة.

1. Consider XLSX as a zip file. Rename *.xlsx into *.zip
2. Unzip
3. Go to unzipped folder root and open /docprops/app.xml
4. This xml contains the sheet name in the same order of what you see.
5. Parse the xml and get the sheet names

استكمال: حل آخر - NPOI قد يكون من المفيد هنا http://npoi.codeplex.com/

 FileStream file = new FileStream(@"yourexcelfilename", FileMode.Open, FileAccess.Read);

      HSSFWorkbook  hssfworkbook = new HSSFWorkbook(file);
        for (int i = 0; i < hssfworkbook.NumberOfSheets; i++)
        {
            Console.WriteLine(hssfworkbook.GetSheetName(i));
        }
        file.Close();

هذا الحل يعمل ل XLS. لم أحاول xlsx.

شكر،

إيسن




لا أرى أي وثائق تفيد بأن الطلب في app.xml مضمون ليكون ترتيب الأوراق. هو بالفعل ، ولكن ليس وفقا لمواصفات OOXML.

يتضمن الملف workbook.xml ، على الجانب الآخر ، سمة sheetId ، والتي تحدد التسلسل - من 1 إلى عدد الأوراق. هذا وفقًا لمواصفات OOXML. يتم وصف workbook.xml كمكان حيث يتم الاحتفاظ تسلسل الأوراق.

لذلك قراءة workbook.xml بعد استخراجها من XLSX سيكون توصيتي. ليس app.xml. بدلاً من docProps / app.xml ، استخدم xl / workbook.xml وانظر إلى العنصر ، كما هو موضح هنا -

`

<workbook xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships">
  <fileVersion appName="xl" lastEdited="5" lowestEdited="5" rupBuild="9303" /> 
  <workbookPr defaultThemeVersion="124226" /> 
- <bookViews>
  <workbookView xWindow="120" yWindow="135" windowWidth="19035" windowHeight="8445" /> 
  </bookViews>
- <sheets>
  <sheet name="By song" sheetId="1" r:id="rId1" /> 
  <sheet name="By actors" sheetId="2" r:id="rId2" /> 
  <sheet name="By pit" sheetId="3" r:id="rId3" /> 
  </sheets>
- <definedNames>
  <definedName name="_xlnm._FilterDatabase" localSheetId="0" hidden="1">'By song'!$A$1:$O$59</definedName> 
  </definedNames>
  <calcPr calcId="145621" /> 
  </workbook>

`




طريق اخر:

ملف xls (x) هو عبارة عن مجموعة من ملفات * .xml المخزنة في حاوية * .zip. فك ضغط الملف "app.xml" في المجلد docProps.

<?xml version="1.0" encoding="UTF-8" standalone="true"?>
-<Properties xmlns:vt="http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes" xmlns="http://schemas.openxmlformats.org/officeDocument/2006/extended-properties">
<TotalTime>0</TotalTime>
<Application>Microsoft Excel</Application>
<DocSecurity>0</DocSecurity>
<ScaleCrop>false</ScaleCrop>
-<HeadingPairs>
  -<vt:vector baseType="variant" size="2">
    -<vt:variant>
      <vt:lpstr>Arbeitsblätter</vt:lpstr>
    </vt:variant>
    -<vt:variant>
      <vt:i4>4</vt:i4>
    </vt:variant>
  </vt:vector>
</HeadingPairs>
-<TitlesOfParts>
  -<vt:vector baseType="lpstr" size="4">
    <vt:lpstr>Tabelle3</vt:lpstr>
    <vt:lpstr>Tabelle4</vt:lpstr>
    <vt:lpstr>Tabelle1</vt:lpstr>
    <vt:lpstr>Tabelle2</vt:lpstr>
  </vt:vector>
</TitlesOfParts>
<Company/>
<LinksUpToDate>false</LinksUpToDate>
<SharedDoc>false</SharedDoc>
<HyperlinksChanged>false</HyperlinksChanged>
<AppVersion>14.0300</AppVersion>
</Properties>

الملف هو ملف ألماني (Arbeitsblätter = أوراق العمل). أسماء الجدول (Tabelle3 وغيرها) هي في الترتيب الصحيح. تحتاج فقط إلى قراءة هذه العلامات ؛)

مع تحياتي




جرب هذا. إليك الشفرة للحصول على أسماء الورقات بالترتيب.

    private Dictionary<int,string> GetExcelSheetNames(string fileName)
    {
     Excel.Application _excel = null;
     Excel.Workbook _workBook = null;
     Dictionary<int,string> excelSheets = new Dictionary<int,string>();
     try
     {
      object missing = Type.Missing;
      object readOnly = true;

  Excel.XlFileFormat.xlWorkbookNormal
  _excel = new Excel.ApplicationClass();
  _excel.Visible = false;
  _workBook = _excel.Workbooks.Open(fileName, 0, readOnly, 5, missing,
     missing, true, Excel.XlPlatform.xlWindows, "\\t", false, false, 0, true, true, missing);
  if (_workBook != null)
  {

                   int index = 0; 

   foreach (Excel.Worksheet sheet in _workBook.Sheets)
   {
    // Can get sheet names in order they are in workbook
    excelSheets.Add(++index, sheet.Name);
   }
  }
 }
 catch (Exception e)
 {
  return null;
 }
 finally
 {
  if (_excel != null)
  {

   if (_workBook != null)
   {
    _workBook.Close(false, Type.Missing, Type.Missing);
   }
   _excel.Application.Quit();
  }
  _excel = null;
  _workBook = null;
 }
    return excelSheets;
    }



Related