问题: 在已安装的Office 2010计算机中,我的应用程序必须将空的excel文件(文件A)复制到新的excel文件(文件B)并使用OpenXML库(V2.5)执行某些操作,最后保存到硬盘。之后,我打开文件B,只需添加一个小数据(例如:1)并保存并关闭它。 当我重新打开文件B时,excel抛出一个错误:Excel在'文件B'中找到了不可读的内容你想要恢复这个工作簿的内容......我无法打开它。 以下是我的代码:
static void Main(string[] args)
{
ExportDataSet(@"C:\A.xlsx",@"C:\");
}
public static void Copy(String oldPath, String newPath)
{
FileStream input = null;
FileStream output = null;
try
{
input = new FileStream(oldPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
output = new FileStream(newPath, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite);
var buffer = new byte[32768];
int read;
while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
{
output.Write(buffer, 0, read);
}
}
catch (Exception e)
{
}
finally
{
if (input != null)
{
input.Close();
input.Dispose();
}
if (output != null)
{
output.Close();
output.Dispose();
}
}
}
public static string ExportDataSet(string filePath, string path, int startRow = 10)
{
var pathToSave = path;
if (!Directory.Exists(pathToSave))
Directory.CreateDirectory(pathToSave);
var filename = pathToSave + Guid.NewGuid() + Path.GetExtension(filePath);
Copy(filePath, filename);
var fs = File.Open(filename, FileMode.Open);
{
using (var myWorkbook = SpreadsheetDocument.Open(fs, true))
{
var workbookPart = myWorkbook.WorkbookPart;
var Sheets = myWorkbook.WorkbookPart.Workbook.GetFirstChild<Sheets>().Elements<Sheet>();
var relationshipId = Sheets.First().Id.Value;
var worksheetPart = (WorksheetPart)myWorkbook.WorkbookPart.GetPartById(relationshipId);
var sheetData = worksheetPart.Worksheet.GetFirstChild<SheetData>();
workbookPart.Workbook.Save();
//workbookPart.Workbook.CalculationProperties = new CalculationProperties() { FullCalculationOnLoad = true };
}
fs.Close();
fs.Dispose();
return filename;
}
}
你的缓冲区读写逻辑是错误的。 The second parameter is where it starts to read or write并且您将它传递给零值,因此while的第二次迭代将覆盖第一次迭代中写入的内容,因此如果文件大于缓冲区大小,则会损坏数据。
您的代码应与此类似:
var buffer = new byte[32768];
int totalRead = 0; // Variable to track where to write in the next while iteration
int read;
while ((read = input.Read(buffer, totalRead, buffer.Length)) > 0)
{
output.Write(buffer, totalRead, read);
totalRead += read; // Add to totalRead the amount written so next iteration does append the content at the end.
}