Modifier cellule excel
Bon matin,
Je voudrais modifier quelques cellules déjà existantes fichier excell. J'ai essayé d'utiliser EPPlus et normal OpenXml classes. Cependant je n'ai pas réussi. Dans les deux situations programme ne plante pas, mais toujours de retour de la vieille (non modifié) excel. S'il vous plaît, ce que je fais mal?
Essai 1 - EPPlus:
MemoryStream memoryStream = new MemoryStream();
using (var fs = new FileStream(@"Path\Test.xlsx", FileMode.Open, FileAccess.Read))
{
byte[] buffer = new byte[1024];
int bytesRead = 0;
while ((bytesRead = fs.Read(buffer, 0, buffer.Length)) > 0)
{
memoryStream.Write(buffer, 0, bytesRead);
}
}
using (ExcelPackage excelPackage = new ExcelPackage(memoryStream))
{
ExcelWorkbook excelWorkBook = excelPackage.Workbook;
ExcelWorksheet excelWorksheet = excelWorkBook.Worksheets.First();
excelWorksheet.Cells[1, 1].Value = "Test";
excelWorksheet.Cells[3, 2].Value = "Test2";
excelWorksheet.Cells[3, 3].Value = "Test3";
excelPackage.Save();
}
memoryStream.Position = 0;
return new FileStreamResult(memoryStream, "application/xlsx")
{
FileDownloadName = "Tester.xlsx"
};
Comment je l'ai dit, il retourne la vieille excel. Mais en mode debug, il contient la nouvelle valeur. Il ressemble à memoryStream ne peut pas être modifié.
Essai 2 - OpenXml classes
Stream stream = System.IO.File.Open(@"Path\Test.xlsx", FileMode.Open);
using (SpreadsheetDocument spreadSheet = SpreadsheetDocument.Open(stream, true))
{
WorksheetPart worksheetPart = GetWorksheetPartByName(spreadSheet, "Sheet1");
Cell cell = GetCell(worksheetPart.Worksheet, "C", 3);
cell.CellValue = new CellValue("Testos");
cell.DataType = new EnumValue<CellValues>(CellValues.String);
worksheetPart.Worksheet.Save();
}
stream.Position = 0;
return new FileStreamResult(stream, "application/xlsx")
{
FileDownloadName = "Tester.xlsx"
};
Et les méthodes d'aide:
private static Row GetRow(Worksheet worksheet, uint rowIndex)
{
Row row;
if (worksheet.GetFirstChild<SheetData>().Elements<Row>().Where(r => r.RowIndex == rowIndex).Count() != 0)
{
row = worksheet.Elements<Row>().Where(r => r.RowIndex == rowIndex).FirstOrDefault();
}
else
{
row = new Row() { RowIndex = rowIndex };
worksheet.Append(row);
}
return row;
}
private static Cell GetCell(Worksheet worksheet, string columnName, uint rowIndex)
{
Row row = GetRow(worksheet, rowIndex);
string cellReference = columnName + rowIndex;
if (row.Elements<Cell>().Where(c => c.CellReference.Value == columnName + rowIndex).Count() > 0)
{
return row.Elements<Cell>().Where(c => c.CellReference.Value == cellReference).FirstOrDefault();
}
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;
}
}
private static WorksheetPart GetWorksheetPartByName(SpreadsheetDocument document, string sheetName)
{
IEnumerable<Sheet> sheets = document.WorkbookPart.Workbook.GetFirstChild<Sheets>().Elements<Sheet>().Where(s => s.Name == sheetName);
string relationshipId = sheets.First().Id.Value;
WorksheetPart worksheetPart = (WorksheetPart)document.WorkbookPart.GetPartById(relationshipId);
return worksheetPart;
}
Une fois de plus je vous remercie pour l'aide.
OriginalL'auteur Ademar | 2014-04-19
Vous devez vous connecter pour publier un commentaire.
Le problème dans les deux cas, c'est que la modification de classeur n'est pas enregistré dans le flux:
OriginalL'auteur Jaroslav Jandek
bien que c'est répondu, je vais ajouter à partir de mon expérience.
Il est plus facile d'ouvrir la ExcelPackage de FileInfo au lieu de Flux, puis de le sauvegarder devient plus simple.
OriginalL'auteur Ehud Grand
Vous pouvez utiliser la dll de l'Interopérabilité de Microsoft de modifier des documents office http://msdn.microsoft.com/en-us/library/15s06t57.aspx. Ajouter l' "Microsoft.Office.Interop.Excel.dll" à votre solution. Avec ce code j'ai changé les 2 valeurs de cellule.
J'ai commencé avec Test1 et Test2 qui après le programme en cours d'exécution changé dans les valeurs appropriées.
Avec l'Interop d'utilisation, je ne pense pas qu'il est possible de travailler avec la mémoire des ruisseaux. Comme suggéré par: codeproject.com/Questions/623916/... envisager d'écrire le fichier dans un dossier temporaire, puis, plus tard, de retour à l'utilisateur comme un flux de mémoire
OriginalL'auteur Martijn van Put
Je suis en utilisant ClosedXML où la mise à jour de la valeur d'une cellule est un no-brainer:
Le package NuGet peut être trouvé ici.
OriginalL'auteur Alexander Zeitler