2016-07-05 79 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); 
相关问题