早上好, 我想编辑已经存在的excell文件中的一些单元格。我尝试过使用EPPlus和普通的OpenXml类。但是我失败了。在这两种情况下,程序都不会崩溃但总是返回旧的(未修改的)excel。拜托,我做错了什么?
试验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"
};
我怎么说它返回旧的excel。但在调试模式下,它还包含新值。看起来无法修改memoryStream。
试用2 - OpenXml类
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"
};
辅助方法:
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;
}
再次感谢您的帮助。
答案 0 :(得分:11)
两种情况下的问题是修改后的工作簿不会保存回流:
MemoryStream ms = new MemoryStream();
using (FileStream fs = File.OpenRead(@"Path\Test.xlsx"))
using (ExcelPackage excelPackage = new ExcelPackage(fs))
{
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.SaveAs(ms); // This is the important part.
}
ms.Position = 0;
return new FileStreamResult(ms, "application/xlsx")
{
FileDownloadName = "Tester.xlsx"
};
答案 1 :(得分:8)
虽然我已经回答了这个问题,但我会从我的经验中补充一下。
从FileInfo而不是Stream中打开ExcelPackage更容易,然后保存变得更简单。
FileInfo file = new FileInfo(path);
using (var package = new ExcelPackage(file))
{
ExcelWorkbook workBook = package.Workbook;
ExcelWorksheet currentWorksheet = workBook.Worksheets.SingleOrDefault(w => w.Name == "sheet1");
int totalRows = currentWorksheet.Dimension.End.Row;
int totalCols = currentWorksheet.Dimension.End.Column;
for (int i = 2; i <= totalRows; i++)
{
try
{
currentWorksheet.Cells[i, 1].Value = "AAA";
}
catch (Exception ex)
{
_logger.Error(String.Format("Error: failed editing excel. See details: {0}", ex));
return;
}
}
package.Save();
答案 2 :(得分:7)
您可以使用Microsoft的Interop dll编辑Office文档http://msdn.microsoft.com/en-us/library/15s06t57.aspx。将“Microsoft.Office.Interop.Excel.dll”添加到您的解决方案中。使用此代码,我已经更改了2个单元格值。
static void Main(string[] args)
{
Application excel = new Application();
Workbook workbook = excel.Workbooks.Open(@"C:\Users\Martijn\Documents\Test.xlsx", ReadOnly: false, Editable:true);
Worksheet worksheet = workbook.Worksheets.Item[1] as Worksheet;
if (worksheet == null)
return;
Range row1 = worksheet.Rows.Cells[1, 1];
Range row2 = worksheet.Rows.Cells[2, 1];
row1.Value = "Test100";
row2.Value = "Test200";
excel.Application.ActiveWorkbook.Save();
excel.Application.Quit();
excel.Quit();
}
在程序运行后,我已经开始使用Test1和Test2,并将其更改为正确的值。
答案 3 :(得分:3)
我正在使用ClosedXML更新单元格值是明智的:
var workbook = new XLWorkbook("HelloWorld.xlsx"); // load the existing excel file
var worksheet = workbook.Worksheets.Worksheet(1);
worksheet.Cell("A1").SetValue("Hello World!");
workbook.Save();
可以找到NuGet包here。
答案 4 :(得分:0)
///这可以帮助您在excel文件中设置单元格:使用System.Data.OleDb;
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="feed" class="table timeline">
<tr><td>I'm having lunch right now</td></tr>
<tr><td>This is my first Tweet!!</td></tr>
</table>