En una .Neto de la aplicación de escritorio de windows, yo soy capaz de importar una matriz de cadenas de datos en un rango de celdas ubicadas en la hoja de cálculo de Excel. El código de C# es como sigue:

using Excel = Microsoft.Office.Interop.Excel;

//Create Application, Workbook, and Worksheet
xlApp = new Microsoft.Office.Interop.Excel.Application();
xlWorkBook = xlApp.Workbooks.Add(misValue);
xlWs = (Excel.Worksheet)xlWorkBook.Worksheets.get_Item(1);

//Move data from temp array into Excel spreadsheet.
Excel.Range c1 = (Excel.Range)xlWs.Cells[startRowNum, 1];
Excel.Range c2 = (Excel.Range)xlWs.Cells[startRowNum + myTable.Rows.Count - 1,   Columns.Count];
Excel.Range range = xlWs.get_Range(c1, c2);
range.Value = tempArray;

Estoy tratando de duplicar este proceso en un ASP.Net página web. El uso de Visual Studio 2010 y C#. ¿Cómo puedo hacer esto mismo de la importación de una matriz de cadena en un Open XML SDK 2.0 hoja de cálculo de Excel rango de celdas?

InformationsquelleAutor Tom3609 | 2012-06-12

2 Comentarios

  1. 4

    Como respondido, una biblioteca puede ser más fácil de usar. Una alternativa de la biblioteca de elección es SpreadsheetLight. He aquí cómo el código podría ser:

    SLDocument sl = new SLDocument("YourFile.xlsx");
    //row 1 column 1
    sl.SetCellValue(1, 1, "String1");
    //row 1 column 2
    sl.SetCellValue(1, 2, "String2");
    sl.SaveAs("AnotherFile.xlsx");

    Usted no tiene que preocuparse acerca de que el fin de establecer los valores de celda. Internamente, SpreadsheetLight se ejecuta en Open XML SDK. Descargo de responsabilidad: yo escribí SpreadsheetLight.

  2. 3

    El uso de la OpenXML SDK directamente en lugar de ir a través de Excel del modelo de automatización es mucho más complejo y propenso a errores. Por lo tanto, recomiendo el uso de una biblioteca para esto; especialmente si la tarea se vuelve más complejo (por ejemplo,http://excelpackage.codeplex.com/).
    Editar: Un ejemplo en hacer algo similar con ExcelPackage se puede encontrar aquí: http://excelpackage.codeplex.com/wikipage?title=Using%20a%20template%20to%20create%20an%20Excel%20spreadsheet Aunque no tengo idea de en qué rendimiento esperar comparación con el uso de la cruda SDK, me imagino que ExcelPackage es usando el SDK internamente de todos modos y por lo tanto se podría producir una sobrecarga. Probablemente sólo una medida para usted escenario concreto puede dar una respuesta definitiva aquí.

    Si quieres seguir con el SDK aunque aquí es un ejemplo para la inserción de las cadenas en un libro de Excel:

    string filePath = "workbook.xlsx";
    string sheetName = "Sheet1";
    uint startRow = 9;
    string columnName = "C";
    string[] data = new string[] { "A", "B", "C" };
    using (var spreadsheetDocument = SpreadsheetDocument.Open(filePath, true))
    {
    //Find the Id of the worksheet in question
    var sheet = spreadsheetDocument.WorkbookPart.Workbook
    .Sheets.Elements<Sheet>()
    .Where(s => s.Name == sheetName).First();
    var sheetReferenceId = sheet.Id;
    //Map the Id to the worksheet part
    WorksheetPart worksheetPart = (WorksheetPart)spreadsheetDocument.WorkbookPart.GetPartById(sheetReferenceId);
    var sheetData = worksheetPart.Worksheet.GetFirstChild<SheetData>();
    //Inset the data at the given location
    for (uint i = 0; i < data.Length; i++)
    {
    uint rowNumber = startRow + i;
    //Find the XML entry for row i
    var row = sheetData.Elements<Row>().Where(r => r.RowIndex == rowNumber).FirstOrDefault();
    if (row == null)
    {
    //Row does not exist yet, create it
    row = new Row();
    row.RowIndex = rowNumber;
    //Insert the row at its correct sequential position
    Row rowAfter = null;
    foreach (Row otherRow in sheetData.Elements<Row>())
    {
    if (otherRow.RowIndex > row.RowIndex)
    {
    rowAfter = otherRow;
    break;
    }
    }
    if (rowAfter == null)
    //New row is the last row in the sheet
    sheetData.Append(row);
    else
    sheetData.InsertBefore(row, rowAfter);
    }
    //CellReferences in OpenXML are "normal" Excel cell references, e.g. D15
    string cellReference = columnName + rowNumber.ToString();
    //Find cell in row
    var cell = row.Elements<Cell>()
    .Where(c => c.CellReference == cellReference)
    .FirstOrDefault();
    if (cell == null)
    {
    //Cell does not exist yet, create it
    cell = new Cell();
    cell.CellReference = new StringValue(cellReference);
    //The cell must be in the correct position (e.g. column B after A)
    //Note: AA must be after Z, so a normal string compare is not sufficient
    Cell cellAfter = null;
    foreach (Cell otherCell in row.Elements<Cell>())
    {
    //This is ugly, but somehow the row number must be stripped from the
    //cell reference for comparison
    string otherCellColumn = otherCell.CellReference.Value;
    otherCellColumn = otherCellColumn.Remove(otherCellColumn.Length - rowNumber.ToString().Length);
    //Now compare first to length and then alphabetically
    if (otherCellColumn.Length > columnName.Length ||
    string.Compare(otherCellColumn, columnName, true) > 0)
    {
    cellAfter = otherCell;
    break;
    }
    }
    if (cellAfter == null)
    //New cell is last cell in row
    row.Append(cell);
    else
    row.InsertBefore(cell, cellAfter);
    }
    //Note: This is the most simple approach.
    //      Normally Excel itself will store the string as a SharedString,
    //      which is more difficult to implement. The only drawback of using
    //      this approach though, is that the cell might have been the only
    //      reference to its shared string value, which is not deleted from the
    //      list here.
    cell.DataType = CellValues.String;
    cell.CellValue = new CellValue(data[i]);
    }
    }

    Por favor, tenga en cuenta que este ejemplo no es perfecto ya que no consideran escenarios complejos en todo (por ejemplo, el estilo, la impresión de margen, celdas combinadas…). Para uso en producción, puede que desee extraer ciertas funciones en un método (por ejemplo, la inserción de una fila o celda en la posición correcta) o, incluso, en una clase por sí mismo (por ejemplo, la parte sobre la comparación de las referencias de celda en el orden correcto).

    Editar:
    El rendimiento de utilizar el SDK en lugar de ir a través de la Automatización de la Modelo es MUCHO mejor (esta es probablemente la segunda gran ventaja de la SDK, siendo el primero que no neeed tener instalado Excel). Si aún se puede ver cuellos de botella de rendimiento aquí están algunas ideas para la mejora:

    1. Asegúrese de que las células ya se han creado en la plantilla de documento (por ejemplo, introduzca un 0 en cada uno de los el uso de Excel). Esto le ahorra el esfuerzo para crear nuevas células.
    2. Asegúrese de que ninguna de las células ya existe en la plantilla y, a continuación, crear todas las células en la secuencia (se ahorra el esfuerzo para encontrar la correcta posición de inserción, al menos para la fila).
    3. Manipular el XML directamente, lo que es más difícil y requiere más conocimiento del funcionamiento interno de OpenXML. Este es probablemente aceptable para más uniforme de los documentos.
    • Gracias, por tu respuesta… La razón por la que estoy tratando de encontrar un método similar al de get_Range es que get_Range es mucho más rápido en la carga de una hoja de cálculo con un gran número de filas y columnas. Cuando me bucle a través de la creación de cada celda de cada fila y de agregar una a una las filas se necesita mucho tiempo para crear la hoja de cálculo. ¿ExcelPackage tener un método para hacerlo más rápido?

Dejar respuesta

Please enter your comment!
Please enter your name here