2016-07-05 115 views
1

目前我做我的頭了在MSDN網站上這裏的OpenXML的2.5框架的工作,https://msdn.microsoft.com/en-us/library/office/cc861607.aspxOPENXML添加單元格到工作表

所有方法我都試過細胞添加到現有工作表腐敗工作簿作爲MSDN站點只概述創建工作表並且不修改它。

每次添加單元格時,系統都需要一個全新的工作表,並且不允許將單元格添加到現有的工作表中。我在MSDN上敲了幾個小時,並且沒有運氣就用Google搜索。

問題是我需要一個可以接收字符串並更新excel文件的類。有沒有人能夠將細胞添加到現有的工作表?我的問題似乎是由於字符串字符串解決方案。

工作輸入(PowerShell中)僅當單元格中創建一個新的工作表的工作原理,

[CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact='Medium')] 
$cSharpData = (
    [Reflection.Assembly]::LoadWithPartialName("DocumentFormat.OpenXml"), 
    [Reflection.Assembly]::LoadWithPartialName("WindowsBase"), 
    [Reflection.Assembly]::LoadWithPartialName("System.Linq") 
) 
[String]$cSharpClass = Get-Content .\method.cs 
$cSharpType = Add-Type -ReferencedAssemblies $cSharpData -TypeDefinition $cSharpClass 

$testData = Get-WmiObject Win32_QuickFixEngineering 
[DoExcelMethod]::CreateXLSX('.\test.xlsx') 

$locNo = 1 
[DoExcelMethod]::AddSheetData('.\test.xlsx', $testData, 'TestWS', 'A', $locNo) 

的文件,這是在點具有以下,

using System; 
using System.Linq; 
using DocumentFormat.OpenXml; 
using DocumentFormat.OpenXml.Packaging; 
using DocumentFormat.OpenXml.Spreadsheet; 

public class DoExcelMethod { 

    private static int SharedDataItem(string sData, SharedStringTablePart ssPart) { 
     if (ssPart.SharedStringTable == null) { 
      ssPart.SharedStringTable = new SharedStringTable(); 
     } 
     int cnt = 0; 
     foreach (SharedStringItem sspItem in ssPart.SharedStringTable.Elements<SharedStringItem>()) { 
      if (sspItem.InnerText == sData) { 
       return cnt; 
      } 
      cnt++; 
     } 
     ssPart.SharedStringTable.AppendChild(new SharedStringItem(new DocumentFormat.OpenXml.Spreadsheet.Text(sData))); 
     ssPart.SharedStringTable.Save(); 
     return cnt; 
    } 

    private static WorksheetPart InsertWorksheet(string wsName, WorkbookPart wbPart) { 
     WorksheetPart newWsPart = wbPart.AddNewPart<WorksheetPart>(); 
     newWsPart.Worksheet = new Worksheet(new SheetData()); 
     newWsPart.Worksheet.Save(); 
     Sheets sheets = wbPart.Workbook.GetFirstChild<Sheets>(); 
     string relId = wbPart.GetIdOfPart(newWsPart); 
     uint sheetId = 1; 
     if (sheets.Elements<Sheet>().Count() > 0) { 
      sheetId = sheets.Elements<Sheet>().Select(s => s.SheetId.Value).Max() + 1; 
     } 
     Sheet sheet = new Sheet() { Id = relId, SheetId = sheetId, Name = wsName }; 
     sheets.Append(sheet); 
     wbPart.Workbook.Save(); 
     return newWsPart; 
    } 

    private static Cell InsertCellInWorksheet(string columnName, uint rowIndex, WorksheetPart worksheetPart) { 
     Worksheet worksheet = worksheetPart.Worksheet; 
     SheetData sheetData = worksheet.GetFirstChild<SheetData>(); 
     string cellReference = columnName + rowIndex; 
     Row row; 
     if (sheetData.Elements<Row>().Where(r => r.RowIndex == rowIndex).Count() != 0) { 
      row = sheetData.Elements<Row>().Where(r => r.RowIndex == rowIndex).First(); 
     } else { 
      row = new Row() { RowIndex = rowIndex }; 
      sheetData.Append(row); 
     } 
     if (row.Elements<Cell>().Where(c => c.CellReference.Value == columnName + rowIndex).Count() > 0) { 
      return row.Elements<Cell>().Where(c => c.CellReference.Value == cellReference).First(); 
     } else { 
      Cell refCell = null; 
      foreach (Cell cell in row.Elements<Cell>()) { 
       if (string.Compare(cell.CellReference.Value, cellReference, true) > 0) { 
        refCell = cell; 
        break; 
       } 
      } 
      Cell newCell = new Cell() { CellReference = cellReference }; 
      row.InsertBefore(newCell, refCell); 
      worksheet.Save(); 
      return newCell; 
     } 
    } 

    public static void CreateXLSX(string xlsxFile) { 
     SpreadsheetDocument spreadsheetDocument = SpreadsheetDocument.Create(xlsxFile, SpreadsheetDocumentType.Workbook); 
     WorkbookPart workbookpart = spreadsheetDocument.AddWorkbookPart(); 
     workbookpart.Workbook = new Workbook(); 
     WorksheetPart worksheetPart = workbookpart.AddNewPart<WorksheetPart>(); 
     worksheetPart.Worksheet = new Worksheet(new SheetData()); 
     Sheets sheets = spreadsheetDocument.WorkbookPart.Workbook.AppendChild<Sheets>(new Sheets()); 
     Sheet sheet = new Sheet() { Id = spreadsheetDocument.WorkbookPart.GetIdOfPart(worksheetPart), SheetId = 1, Name = "Default" }; 
     sheets.Append(sheet); 
     workbookpart.Workbook.Save(); 
     spreadsheetDocument.Close(); 
    } 

    public static void AddSheetData(string xlsxFile, string psData, string wsName, string psCol, uint psRow) { 
     using (SpreadsheetDocument sSheet = SpreadsheetDocument.Open(xlsxFile, true)) { 
      SharedStringTablePart ssPart; 
      if (sSheet.WorkbookPart.GetPartsOfType<SharedStringTablePart>().Count() > 0) { 
       ssPart = sSheet.WorkbookPart.GetPartsOfType<SharedStringTablePart>().First(); 
      } else { 
       ssPart = sSheet.WorkbookPart.AddNewPart<SharedStringTablePart>(); 
      } 
      int ssIns = SharedDataItem(psData, ssPart); 
      WorksheetPart wsPart = InsertWorksheet(wsName, sSheet.WorkbookPart); 
      Cell cell = InsertCellInWorksheet(psCol, psRow, wsPart); 
      cell.CellValue = new CellValue(ssIns.ToString()); 
      cell.DataType = new EnumValue<CellValues>(CellValues.SharedString); 
      wsPart.Worksheet.Save(); 
     } 
    } 
} 

因此,儘管這個工作,我不能得到一個單元格到現有的工作表,任何人都可以幫助,因爲我瘋了:(

謝謝所有

+0

的OpenXML替換該行

WorksheetPart wsPart = InsertWorksheet(wsName, sSheet.WorkbookPart); 

是在這個意義上,它是可偉大的,但壞的,因爲它是殘酷的困難的工作,彷彿微軟沒有按」我們真的很想要。好消息是,對於Excel,您可以使用[EPPlus](http://epplus.codeplex.com/),它提供了更容易處理的語法。我會直接使用它。 –

+0

還有一個名爲closedXML的庫,當我必須在c#中創建excel時,它使用非常簡單,例如創建文件,工作表和單元格https://closedxml.codeplex.com –

+0

感謝Scott,關注鏈接我看到這是指Office 2007/Office 2010.你知道這是否適用於Office 2013/2016?我有兩個完全可行的解決方案,一個使用PowerShell Export-XLSX,但這是Office 2007,不適用於Office 2013/16,另一個是打開Excel並粘貼數據(通過代碼),但不能在服務器上許可Excel 。感謝 – jaradsc

回答

2

您遇到的問題是InsertWorksheet的電話AddSheetData。無論工作表是否已存在,您都在調用InsertWorksheet方法。而不是這樣做,你可以先搜索工作表,如果它存在,你可以使用它,如果不是,你可以創建一個新的。

首先,你可以使用的方法搜索WorksheetPart它的名字像這樣的(從我的答案here拍攝):

private static WorksheetPart GetWorksheetPartBySheetName(WorkbookPart workbookPart, string sheetName) 
{ 
    WorksheetPart worksheetPart = null; 

    //find the sheet (note this is case-sensitive) 
    IEnumerable<Sheet> sheets = workbookPart.Workbook.GetFirstChild<Sheets>().Elements<Sheet>().Where(s => s.Name == sheetName); 

    if (sheets.Count() > 0) 
    { 
     string relationshipId = sheets.First().Id.Value; 
     worksheetPart = (WorksheetPart)workbookPart.GetPartById(relationshipId); 
    } 

    return worksheetPart; 
} 

如果該方法找到WorksheetPart那麼它將返回它,如果不會返回null

一旦你有,你只需要一個小的調整,以AddSheetDataGetWorksheetPartBySheetName則只能調用InsertWorksheet如果該方法返回null。要做到這一點,你可以用這個

WorksheetPart wsPart = GetWorksheetPartBySheetName(sSheet.WorkbookPart, wsName); 
if (wsPart == null) 
    wsPart = InsertWorksheet(wsName, sSheet.WorkbookPart); 
相關問題