[研究]ASP.NET,WebForm,免ODS套件寫入匯出.ods
2024-10-29
環境:Visual Studio 2022 + ASP.NET + WebForm + Web Application + C# + SQL Server 2019 + SQL Server Management Studio (SSMS) 19
********************************************************************************
Default.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default2.aspx.cs"
Inherits="WebApplication1.Default2" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title></title>
</head>
<body>
<form id="form1" runat="server">
</form>
</body>
</html>
|
Default.aspx.cs
using System;
using System.IO;
using System.IO.Compression;
namespace WebApplication1
{
public partial class Default2 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
GenerateOdsFile();
}
private void GenerateOdsFile()
{
using (MemoryStream odsStream = new MemoryStream())
{
using (ZipArchive zip = new ZipArchive(odsStream, ZipArchiveMode.Create, true))
{
// 添加 mimetype 檔案
ZipArchiveEntry mimeEntry = zip.CreateEntry("mimetype", CompressionLevel.NoCompression);
using (StreamWriter writer = new StreamWriter(mimeEntry.Open()))
{
writer.Write("application/vnd.oasis.opendocument.spreadsheet");
}
// 添加必要的 META-INF/manifest.xml 文件
ZipArchiveEntry manifestEntry = zip.CreateEntry("META-INF/manifest.xml", CompressionLevel.Fastest);
using (StreamWriter writer = new StreamWriter(manifestEntry.Open()))
{
writer.Write(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<manifest:manifest xmlns:manifest=\"urn:oasis:names:tc:opendocument:xmlns:manifest:1.0\">\n" +
" <manifest:file-entry manifest:full-path=\"/\" manifest:media-type=\"application/vnd.oasis.opendocument.spreadsheet\"/>\n" +
" <manifest:file-entry manifest:full-path=\"content.xml\" manifest:media-type=\"text/xml\"/>\n" +
"</manifest:manifest>"
);
}
// 添加 content.xml 文件
ZipArchiveEntry contentEntry = zip.CreateEntry("content.xml", CompressionLevel.Fastest);
using (StreamWriter writer = new StreamWriter(contentEntry.Open()))
{
writer.Write(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<office:document-content xmlns:office=\"urn:oasis:names:tc:opendocument:xmlns:office:1.0\" " +
"xmlns:table=\"urn:oasis:names:tc:opendocument:xmlns:table:1.0\" " +
"xmlns:text=\"urn:oasis:names:tc:opendocument:xmlns:text:1.0\" " +
"xmlns:style=\"urn:oasis:names:tc:opendocument:xmlns:style:1.0\" " +
"office:version=\"1.2\">\n" +
"<office:body><office:spreadsheet><table:table table:name=\"Sheet1\" table:style-name=\"ta1\">\n" +
"<table:table-column table:style-name=\"co1\" table:number-columns-repeated=\"2\"/>\n" +
"<table:table-row table:style-name=\"ro1\"><table:table-cell><text:p>資料1</text:p></table:table-cell>" +
"<table:table-cell><text:p>資料2</text:p></table:table-cell></table:table-row>\n" +
"<table:table-row table:style-name=\"ro1\"><table:table-cell><text:p>資料3</text:p></table:table-cell>" +
"<table:table-cell><text:p>資料4</text:p></table:table-cell></table:table-row>\n" +
"</table:table></office:spreadsheet></office:body></office:document-content>"
);
}
}
odsStream.Position = 0;
Response.Clear();
Response.ContentType = "application/vnd.oasis.opendocument.spreadsheet";
Response.AddHeader("Content-Disposition", "attachment; filename=sample.ods");
odsStream.CopyTo(Response.OutputStream);
Response.Flush();
Response.End();
}
}
//---
}
}
|
結果 LibreOffice 7.6 正常讀取,但 Excel 2021開啟有警告,修復後正常顯示。這是因為Excel 對 .ods 文件有較嚴格的要求,尤其是 XML 標籤和屬性的結構。敝人嘗試多次,暫時仍無法解決,或許可以一開始用 LibreOffice建立一個正常的 template.ods 給程式插入資料使用。
Default.aspx.cs
using System;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Xml.Linq;
namespace WebApplication1
{
public partial class Default3 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
string odsFilePath = @"C:\Users\Administrator\Downloads\Template2.ods";
string targetOdsPath = @"C:\Users\Administrator\Downloads\S2.ods";
File.Copy(odsFilePath, targetOdsPath, overwrite: true);
InsertDataToODS(targetOdsPath);
}
public void InsertDataToODS(string odsFilePath)
{
// 定義要插入的資料
var data = new string[,]
{
{ "A1", "B1" },
{ "A2", "B2" }
};
// 打開 .ods 檔案 (實際上是 Zip 檔案)
using (var zip = ZipFile.Open(odsFilePath, ZipArchiveMode.Update))
{
// 尋找 content.xml
var entry = zip.GetEntry("content.xml");
if (entry == null)
{
throw new FileNotFoundException("content.xml not found in the .ods file.");
}
// 讀取 content.xml 並載入 XML 文件
XDocument doc;
using (var stream = entry.Open())
{
doc = XDocument.Load(stream);
}
// 尋找要插入資料的表格位置 (這裡假設是 Sheet1)
XNamespace ns = "urn:oasis:names:tc:opendocument:xmlns:table:1.0";
var sheet = doc.Descendants(ns + "table").FirstOrDefault();
if (sheet != null)
{
// 生成 2x2 表格的 Row 和 Cell
for (int i = 0; i < 2; i++)
{
var row = new XElement(ns + "table-row");
for (int j = 0; j < 2; j++)
{
var cell = new XElement(ns + "table-cell",
new XElement(ns + "p", data[i, j]));
row.Add(cell);
}
sheet.Add(row);
}
}
// 將修改後的 XML 內容重新寫入 content.xml
using (var stream = entry.Open())
{
stream.SetLength(0); // 清除原始內容
doc.Save(stream);
}
}
}
//---
}
}
|
實際測試,還是有問題,在無 ODS 套件情況,想自己或靠 ChatGPT 的 Code 產出 Excel 2021 可以正常讀取的 .ods 並不容易,運氣好是警告,然後可以讀取,運氣不好是完全不能讀取。
(完)
相關




沒有留言:
張貼留言