.xlsx 使用带有 EPPlus 的模板创建和保存是不可读/损坏的
本文关键字:保存 损坏 EPPlus xlsx 创建 | 更新日期: 2023-09-27 18:35:10
问题
我正在尝试创建一个小程序,该程序使用 Excel 模板创建 Excel 文档,然后使用 EPPlus 写入多个单元格。不幸的是,无论我尝试什么,文件似乎都已损坏。
我的代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using OfficeOpenXml;
using System.IO;
namespace ConsoleApplication9
{
public sealed class ExcelSerialize
{
private readonly List<Tuple<string, string>> Results;
private readonly string Directory;
private ExcelPackage package;
public ExcelSerialize(List<Tuple<string, string>> Results, string Directory)
{
this.Results = Results;
this.Directory = Directory;
}
public bool WriteResults()
{
FileInfo template = new FileInfo(Directory);
using (package = new ExcelPackage(template, true))
{
ExcelWorksheet worksheet = package.Workbook.Worksheets[1];
//foreach (Tuple<string, string> Result in Results)
//{
// worksheet.Cells[Result.Item1].Value = Result.Item2;
//}
string file = string.Format(System.AppDomain.CurrentDomain.BaseDirectory.ToString() + @"results'results" + System.DateTime.Now.ToString().Replace(" ", "").Replace("/", "_").Replace(":", "-") + ".xlsx");
Byte[] bin = package.GetAsByteArray();
File.WriteAllBytes(file, bin);
return true;
}
}
}
}
我尝试过的事情:
- 更改模板中各个单元格的值。
- 保存从模板创建的 Excel 文档,而不向其写入任何新数据。
- 创建一个基本模板,其中单元格 A1、A2 和 A3 包含"TEST",没有其他编辑,而不是我打算使用的更复杂的模板。
- 使用
Package.SaveAs()
保存。 - 使用示例代码中显示的 Byte 数组进行保存。
- 从 Codeplex 上提供的最新源代码编译 EPPlus。
有效方法:
- 使用以下代码创建新文件:
using (package = new ExcelPackage(string.Format(System.AppDomain.CurrentDomain.BaseDirectory.ToString() + @"results'results" + System.DateTime.Now.ToString().Replace(" ", "").Replace("/", "_").Replace(":", "-") + ".xlsx"))
{
ExcelWorksheet worksheet = package.Workbook.Worksheets.Add("Test");
worksheet.Cells[A1].Value = "Test";
package.Save();
}
笔记:
无论出于何种原因,保存的文件仍然显示为损坏且无法恢复。我当前使用的是 Microsoft Office 2010。我使用的文件格式是 .xltx
和 .xlsx
.
简短回答:
EPPlus 库不支持从现有的 xltx Excel 模板创建文件。
请改用预先格式化的 xlsx 文件。
长答案:
Dim excelFile As New FileInfo(filename)
Dim reportTemplate As New FileInfo(templatePath)
Dim xlFile As ExcelPackage = New ExcelPackage(excelFile, reportTemplate)
' Do Stuff
xlFile.Save()
当使用 EPPlus 实例化一个新的 ExcelPackage 对象时,您应该能够提供一个模板作为第二个参数(请参阅上面的代码片段),但是当它与 xltx 文件一起提供时,我不断得到一个与上面的用户相同的损坏输出文件。我最终发现提供常规的 xlsx 文件作为模板,而不是实际的模板文件,似乎有效。
这是一个开源包,所以我决定快速浏览一下源代码。
看起来就像接受"template"参数的ExcelPackage构造函数一样,调用CreateFromTemplate()方法。对 CreateFromTemplate() 方法的注释指出,它希望将现有的 xlsx 文件用作模板,而不是实际的模板文件。
因此,虽然人们可能会假设"模板"参数指的是实际的 xltx 模板文件,但 EPPlus 似乎不支持这一点。
类似的问题面临,只需将模板还给我即可
public ExcelPackage getSheet(string templatePath){
FileInfo template = new FileInfo(templatePath);
ExcelPackage p = new ExcelPackage(template, true);
ExcelWorksheet ws = p.Workbook.Worksheets[1]; //position of the worksheet
ws.Name = bookName;
p.Save();
ExcelPackage pck = new ExcelPackage(new System.IO.MemoryStream(), p.Stream);
return pck;
然后你用这个打电话
string path = Server.MapPath(@"../../../Ex/template.xlsx")
try
{
OfficeOpenXml.ExcelPackage pck = getSheet(path);
Response.Clear();
Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
Response.AddHeader("content-disposition", String.Format(System.Globalization.CultureInfo.InvariantCulture, "attachment; filename={0}", fileName + ".xlsx"));
Response.BinaryWrite(pck.GetAsByteArray());
Response.End();
}
catch { }
将数据
写入文件后显式关闭该文件。我知道当您在 Web 请求的响应中使用 EPPlus 时,关闭响应会消除该问题。