顯示具有 ods 標籤的文章。 顯示所有文章
顯示具有 ods 標籤的文章。 顯示所有文章

2025年6月6日 星期五

[研究]用ProDotNetZip取代DotNetZip處理.ods

[研究]用ProDotNetZip取代DotNetZip處理.ods

2025-06-06

********************************************************************************

DotNetZip 最後版本 1.16.0

https://www.nuget.org/packages/dotnetzip/

This package has at least one vulnerability with high severity. It may lead to specific problems in your project. Try updating the package version.

This package has been deprecated as it is legacy and is no longer maintained.

此軟體包至少存在一個高危險漏洞。這可能會導致您的項目出現特定問題。請嘗試更新軟體包版本。

此軟體包已被棄用,因為它是舊版本,並且不再維護。

****************************************

上面畫面點右邊 Project website 後

https://github.com/haf/DotNetZip.Semverd
Please use System.IO.Compression! A fork of the DotNetZip project without signing with a solution that compiles cleanly. This project aims to follow semver to avoid versioning conflicts. DotNetZip is a FAST, FREE class library and toolset for manipulating zip files. Use VB, C# or any .NET language to easily create, extract, or update zip files.

請使用 System.IO.Compression! DotNetZip 專案的 fork 版本,無需簽名,可乾淨編譯。本專案旨在遵循語義版本控制 (semver) 以避免版本衝突。 DotNetZip 是一個快速、免費的類別庫和工具集,用於處理 zip 檔案。您可以使用 VB、C# 或任何 .NET 語言輕鬆建立、提取或更新 zip 檔案。

********************************************************************************

ProDotNetZip - NET Standard part of DotNetZip / Ionic's Zip Library
https://www.nuget.org/packages/ProDotNetZip

ProDotNetZip 沿用了 DotNetZip/Ionic Zip 原始程式碼,但僅限於 .NET Standard 部分,而非整個。命名空間保持不變,為 Ionic.Zip。

********************************************************************************

(完)

相關

[研究]用ProDotNetZip取代DotNetZip處理.ods
https://shaurong.blogspot.com/2025/06/prodotnetzipdotnetzipods.html

[研究]ASP.NET,WebForm, 把 OdsReadWrite.cs 從 Ionic.Zip 或 DotNetZip 改成用 System.IO.Compression
https://shaurong.blogspot.com/2024/03/aspnetwebform-odsreadwritecs-ioniczip.html

[研究]ASP.NET,WebForm,用 OdsReaderWriter + DotNetZip (Ionic.Zip) 1.16.0 共用匯出 .ods
https://shaurong.blogspot.com/2024/03/aspnetwebform-odsreaderwriter-dotnetzip_79.html

[研究]ASP.NET,WebForm,用 OdsReaderWriter + DotNetZip (Ionic.Zip) 1.16.0 匯出 .ods
https://shaurong.blogspot.com/2024/03/aspnetwebform-odsreaderwriter-dotnetzip_23.html

[研究]ASP.NET,WebForm,用 OdsReaderWriter + DotNetZip (Ionic.Zip) 1.16.0 匯入 .ods
https://shaurong.blogspot.com/2024/03/aspnetwebform-odsreaderwriter-dotnetzip_93.html

How to Read and Write ODF/ODS Files (OpenDocument Spreadsheets) - CodeProject
https://www.codeproject.com/Articles/38425/How-to-Read-and-Write-ODF-ODS-Files-OpenDocument-2

[研究][ASP.NET]讀取、匯出、寫入、匯入 Excel .xlsx .xls ODF .ods
https://shaurong.blogspot.com/2020/04/caspnetwebform-excel-xlsx-xls-odf-ods.html

[研究][ASP.NET]使用 OdsReaderWriter + DotNetZip 1.15.0 (Ionic.Zip) 匯出寫入 .ods
https://shaurong.blogspot.com/2021/02/aspnet-odsreaderwriter-dotnetzip-1150_9.html

[研究][ASP.NET]使用 OdsReaderWriter + DotNetZip 1.15.0 讀取匯入 .ods 到資料庫
https://shaurong.blogspot.com/2021/02/aspnet-odsreaderwriter-dotnetzip-1150.html

[研究][C#]用OdsReaderWrite匯出(寫入)、匯入(讀取) ODF/.ods 檔案 (使用 Ionic.Zip、DotNetZip)
https://shaurong.blogspot.com/2020/09/caspnetwebform-ioniczip-odfods.html

[研究] [C#] 用OdsReadWrite讀取 LibreOffice、OpenOffice 的試算表(Calc) 檔案 (.ods)(使用 .NET 4.5 的 ZipFile)
https://shaurong.blogspot.com/2016/12/c-libreoffice-516-calc-ods-net-45.html

[研究] [C#] 用OdsReaderWrite讀取 LibreOffice 5.1.6 的試算表(Calc) 檔案 (.ods)(使用 DotNetZip)
https://shaurong.blogspot.com/2016/12/c-libreoffice-516-calc-ods.html

NuGet Gallery | OdsReaderWriter 1.0.10
https://www.nuget.org/packages/OdsReaderWriter

sortings/OdsReadWrite at master · Luviz/sortings · GitHub
https://github.com/Luviz/sortings/tree/master/OdsReadWrite

2024年11月8日 星期五

[研究]ASP.NET,WebForm,用 FreeDataExports 1.1.11 匯出 SqlDataSource1 資料成 .ods (MIT)

[研究]ASP.NET,WebForm,用 FreeDataExports 1.1.11 匯出 SqlDataSource1 資料成 .ods (MIT)

2024-11-08

環境:Visual Studio 2022 + ASP.NET + WebForm + Web Application + C# + SQL Server 2019 + SQL Server Management Studio (SSMS) 19

********************************************************************************

https://www.nuget.org/packages/FreeDataExports/1.1.11/License

授權是 MIT



********************************************************************************

官方網站
https://github.com/ryankueter/FreeDataExports

官方的程式範例有問題。

Web.Config

<?xml version="1.0" encoding="utf-8"?>
<!--
  如需如何設定 ASP.NET 應用程式的詳細資訊,請前往
  https://go.microsoft.com/fwlink/?LinkId=169433
  -->
<configuration>
  <connectionStrings>
    <add name="MyDBConnectionString" connectionString="Data Source=.;Initial Catalog=MyDB;User ID=sa;Password=密碼"
      providerName="System.Data.SqlClient" />
  </connectionStrings>
  <system.web>
    <compilation debug="true" targetFramework="4.8" />
    <httpRuntime targetFramework="4.8" />
  </system.web>
  <system.codedom>
    <compilers>
      <compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:default /nowarn:1659;1699;1701" />
      <compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:default /nowarn:41008 /define:_MYTYPE=\&quot;Web\&quot; /optionInfer+" />
    </compilers>
  </system.codedom>
</configuration>

Default.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication1.Default" %>

<!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">
        <asp:SqlDataSource ID="SqlDataSource_Field2" runat="server"
            ConnectionString="<%$ ConnectionStrings:MyDBConnectionString %>"
            SelectCommand="SELECT N'全部' AS [Field2], 0 AS Priority
            UNION
            SELECT DISTINCT [Field2], 1 AS Priority FROM [MyTable] ORDER BY Priority, [Field2]"></asp:SqlDataSource>
        <asp:DropDownList ID="DropDownList_Field2" runat="server"
            AutoPostBack="True" DataSourceID="SqlDataSource_Field2"
            DataTextField="Field2" DataValueField="Field2">
        </asp:DropDownList>
        <br />
        <asp:Button ID="Button_Export_ODS" runat="server" Text="匯出(.ods)"
            OnClick="Button_Export_ODS_Click" /><br />
        <asp:Button ID="Button_Export_ODS2" runat="server" Text="匯出2(.ods)"
            OnClick="Button_Export_ODS2_Click" /><br />
        <asp:Button ID="Button_Export_ODS3" runat="server" Text="匯出3(.ods)"
            OnClick="Button_Export_ODS3_Click" /><br />
        <asp:Label ID="Label_MSG1" runat="server" Text="Label"></asp:Label>
        <br />
        <asp:SqlDataSource ID="SqlDataSource1" runat="server"
            ConnectionString="<%$ ConnectionStrings:MyDBConnectionString %>"
            SelectCommand="--TSQL--
            SELECT * FROM [MyTable]
            WHERE ([Field2]=@Filed2 OR @Filed2=N'全部');">
            <SelectParameters>
                <asp:ControlParameter ControlID="DropDownList_Field2" Name="Filed2" PropertyName="SelectedValue" />
            </SelectParameters>
        </asp:SqlDataSource>
        <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="SN" DataSourceID="SqlDataSource1">
            <Columns>
                <asp:BoundField DataField="SN" HeaderText="SN" InsertVisible="False" ReadOnly="True" SortExpression="SN" />
                <asp:BoundField DataField="Field1" HeaderText="Field1" SortExpression="Field1" />
                <asp:BoundField DataField="Field2" HeaderText="Field2" SortExpression="Field2" />
            </Columns>
        </asp:GridView>

    </form>
</body>
</html>

Default.aspx.cs

using System;
using System.Data.SqlClient;

namespace WebApplication1
{
    public partial class Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
        }

        protected void Button_Export_ODS_Click(object sender, EventArgs e)
        {
            string[] columnNameArray = { "流水號", "欄位1", "欄位2" };
            SqlParameter[] sqlParameters = OdsCommon.ConvertParameters(SqlDataSource1.SelectParameters, this.Page);
            OdsCommon.ExportODS("匯出檔案名稱", columnNameArray, SqlDataSource1.SelectCommand, sqlParameters);
        }

        protected void Button_Export_ODS2_Click(object sender, EventArgs e)
        {
            string[] columnNameArray = { "流水號", "欄位1", "欄位2" };
            SqlParameter[] sqlParameters = OdsCommon.ConvertParameters(SqlDataSource1.SelectParameters, this.Page);
            OdsReaderWriterSystemIOCompressionCommon.ExportODS("匯出檔案名稱", columnNameArray, SqlDataSource1.SelectCommand, sqlParameters);
        }
        protected void Button_Export_ODS3_Click(object sender, EventArgs e)
        {
            string[] columnNameArray = { "流水號", "欄位1", "欄位2" };
            SqlParameter[] sqlParameters = OdsFreeDataExportsCommon.ConvertParameters(SqlDataSource1.SelectParameters, this.Page);
            OdsFreeDataExportsCommon.ExportODS("匯出檔案名稱", columnNameArray, SqlDataSource1.SelectCommand, sqlParameters);
        }
    }
}



Default.aspx.cs

using FreeDataExports;
using System;
using System.Data;
using System.Data.SqlClient;
using System.IO;
using System.Web;
using System.Web.Configuration;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace WebApplication1
{
    public class OdsFreeDataExportsCommon
    {
        //【匯出(.ods)】
        #region === public void ExportODS(string odsFilename, string sqlDataSourceSelectCommand) ===
        public static void ExportODS(string odsFilename,
            string[] columnNameArray,
            string sqlDataSourceSelectCommand,
            SqlParameter[] parameters)
        {
            // Import
            // https://docs.microsoft.com/en-us/office/open-xml/how-to-parse-and-read-a-large-spreadsheet

            // Export
            // https://docs.microsoft.com/en-us/office/open-xml/how-to-create-a-spreadsheet-document-by-providing-a-file-name

            //Insert text into a cell in a spreadsheet document(Open XML SDK)
            //https://docs.microsoft.com/zh-tw/office/open-xml/how-to-insert-text-into-a-cell-in-a-spreadsheet

            string mainFileName = odsFilename;

            // 若檔案名稱有中文字或特殊符號,Response.AddHeader() 輸出檔案名稱要編碼
            string outFileName = HttpUtility.UrlEncode(mainFileName, System.Text.Encoding.UTF8) + "-" +
                DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss-fff") + ".ods";

            // XLWorkbook.SaveAs() 輸出檔案名稱不要用 HttpUtility.UrlEncode 編碼
            // Response.TransmitFile() 輸出檔案名稱不要用 HttpUtility.UrlEncode 編碼
            string dirFileName = @"D:\Production\TempImageFiles\" + mainFileName + "-" +
                DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss-fff") + ".ods";
            try
            {
                System.Web.HttpContext.Current.Response.Clear();
                System.Web.HttpContext.Current.Response.Buffer = true;
                System.Web.HttpContext.Current.Response.Charset = "";

                #region === Export ODS ===

                // [EXCEL] Excel打開是亂碼?快速找回資料的最好方法!
                // http://blog.e-happy.com.tw/excel-excel%E6%89%93%E9%96%8B%E6%98%AF%E4%BA%82%E7%A2%BC%EF%BC%9F%E5%BF%AB%E9%80%9F%E6%89%BE%E5%9B%9E%E8%B3%87%E6%96%99%E7%9A%84%E6%9C%80%E5%A5%BD%E6%96%B9%E6%B3%95%EF%BC%81/

                // Excel開啟CSV時的中文編碼問題補遺
                //https://blog.darkthread.net/blog/csv-encoding-again/

                //Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
                System.Web.HttpContext.Current.Response.ContentType = "application/vnd.oasis.opendocument.spreadsheet";    // ODF/.ods
                System.Web.HttpContext.Current.Response.AddHeader("content-disposition", "attachment;filename=" + outFileName);
                using (MemoryStream MyMemoryStream = new MemoryStream())
                {
                    StreamWriter odsFileStreamWriter = new StreamWriter(MyMemoryStream);
                    StreamReader odsFileStreamReader = new StreamReader(new MemoryStream());
                    string dataText = "";

                    DataSet ds = new DataSet("DS1");
                    //DataTable dt = new DataTable();
                    DataTable dt = ds.Tables.Add("工作表1");

                    //                    string[] columnNameArray = {
                    //"流水號"
                    //,"欄位1"
                    //,"欄位2"
                    //        };
                    foreach (string columnName in columnNameArray)
                    {
                        DataColumn dataColumnName = new DataColumn
                        {
                            DataType = System.Type.GetType("System.String"),
                            ColumnName = columnName
                        };
                        dt.Columns.Add(dataColumnName);
                    }

                    DataRow dataColumnNameRow = dt.NewRow();
                    int ii = 0;
                    foreach (string columnName in columnNameArray)
                    {
                        dataColumnNameRow[ii] = columnName;
                        ii++;
                    }
                    dt.Rows.Add(dataColumnNameRow);

                    //string queryString = SqlDataSource.SelectCommand;
                    string queryString = sqlDataSourceSelectCommand;
                    using (SqlConnection connection = new SqlConnection(WebConfigurationManager.ConnectionStrings["MyDBConnectionString"].ConnectionString))
                    {
                        SqlCommand command = new SqlCommand(queryString, connection);
                        //command.Parameters.Clear();
                        //command.Parameters.AddWithValue("@cname", cname);
                        //command.Parameters.AddWithValue("@myemail", myemail);

                        if (parameters != null)
                        {
                            foreach (SqlParameter parameter in parameters)
                            {
                                command.Parameters.Add(parameter);
                            }
                        }

                        connection.Open();

                        //Get All column 
                        //var columnNames = Enumerable.Range(0, reader.FieldCount)
                        //                        .Select(reader.GetName)
                        //                        .ToList();

                        ////Create headers
                        //sb.Append(string.Join(",", columnNames));

                        ////Append Line
                        //sb.AppendLine();


                        try
                        {
                            using (SqlDataReader reader = command.ExecuteReader())
                            {
                                while (reader.Read())
                                {
                                    //Console.WriteLine(String.Format("{0}", reader[0]));
                                    DataRow datarow = dt.NewRow();
                                    for (int i = 0; i < reader.FieldCount; i++)
                                    {
                                        dataText = reader[i].ToString();
                                        // 換掉影響 CSV 顯示效果的字元
                                        dataText = dataText.Replace("\r", "").Replace("\n", "").Replace("\t", "").Replace(",", ",").Replace("'", "′").Replace(@"""", "”");
                                        //if (i > 0)
                                        //{
                                        //    datarow[i - 1] = dataText;
                                        //}
                                        datarow[i] = dataText;
                                        //if (i == 1)
                                        //{
                                        //    //if (csvContent=="")
                                        //    //    csvContent = dataText;
                                        //    //else
                                        //    //csvContent = csvContent + "\r\n" + dataText;
                                        //    csvContent.Append("\r\n" + dataText);

                                        //}
                                        //else
                                        //{
                                        //    //csvContent = csvContent + "," + dataText;
                                        //    csvContent.Append("," + dataText);
                                        //}
                                    }
                                    dt.Rows.Add(datarow);
                                }
                            }

                            var workbook = new DataExport().CreateODSv1_3();
                            var worksheet = workbook.AddWorksheet("工作表1");
                            DataTable dataTable= ds.Tables[0];
                            for (int i = 0; i < dataTable.Rows.Count; i++)
                            {
                                worksheet.AddRow();
                                for (int j = 0; j < dataTable.Columns.Count; j++)
                                    worksheet.AddCell(dataTable.Rows[i].ItemArray[j], DataType.String);
                            }
                            workbook.Save(dirFileName);

                            //OdsReaderWriter odsFile = new OdsReaderWriter();
                            ////odsFile.WriteOdsFile(ds, @"C:\TEMP\1.ods");
                            //odsFile.WriteOdsFile(ds, dirFileName);

                            //Label_MSG1.ForeColor = System.Drawing.Color.Green;
                            //string msg = DateTime.Now.ToString() + "匯出成功。";
                            //Label_MSG1.Text = msg;
                            //Page.ClientScript.RegisterStartupScript(Page.GetType(), "message", "<script language='javascript' defer>alert('" + msg + "');</script>");
                        }
                        catch (Exception)
                        {
                            throw;
                        }
                    }
                    System.Web.HttpContext.Current.Response.TransmitFile(dirFileName);
                    System.Web.HttpContext.Current.Response.End();
                }
                #endregion Export ODS
            }
            catch (Exception)
            {
                throw;
            }
            //Page.ClientScript.RegisterStartupScript(Page.GetType(), "message", "<script language='javascript' defer>alert('匯出成功。');</script>");
        }
        #endregion

        //建立參數
        #region === public static SqlParameter[] ConvertParameters(ParameterCollection parameters, Page page) ===
        public static SqlParameter[] ConvertParameters(ParameterCollection parameters, Page page)
        {
            SqlParameter[] sqlParameters = new SqlParameter[parameters.Count];
            for (int i = 0; i < parameters.Count; i++)
            {
                var parameter = parameters[i];
                if (parameter is ControlParameter)
                {
                    ControlParameter controlParameter = (ControlParameter)parameter;
                    var control = page.FindControl(controlParameter.ControlID);
                    // 確保找到控制元件
                    if (control != null)
                    {
                        string value = (control as ITextControl)?.Text ?? string.Empty;
                        sqlParameters[i] = new SqlParameter(parameter.Name, value);
                    }
                    else
                    {
                        // 找不到控制元件時,應該提供預設值,而不是引發 NullReferenceException
                        sqlParameters[i] = new SqlParameter(parameter.Name, DBNull.Value);
                    }
                }
                else
                {
                    // 如果參數不是控制參數,則使用 DBNull.Value
                    sqlParameters[i] = new SqlParameter(parameter.Name, DBNull.Value);
                }
            }
            return sqlParameters;
        }
        #endregion === public static SqlParameter[] ConvertParameters(ParameterCollection parameters, Page page) ===
    }
}

實際測試可以成功。(按鈕3)

下圖,

下圖,

********************************************************************************

FreeDataExports 庫本身不支援自定義字型顏色、字體大小或粗體格式設定,因為它設計上是簡單的匯出工具,並沒有提供進階的格式化選項。

********************************************************************************

(完)

相關

[研究]ASP.NET,WebForm,用 FreeDataExports 1.1.11 匯出 SqlDataSource1 資料成 .ods (MIT)
https://shaurong.blogspot.com/2024/11/aspnetwebform-freedataexports-1111.html

[研究]ASP.NET,WebForm,用 FreeDataExports 1.1.11 匯出 .ods
https://shaurong.blogspot.com/2024/10/aspnetwebform-freedataexports-1111-ods.html

[研究]ASP.NET,WebForm,要傳遞 SqlDataSource1.SelectParameters 當時的值https://shaurong.blogspot.com/2024/03/aspnetwebform-sqldatasource1selectparam.html

[研究]ASP.NET,WebForm,用 FreeDataExports 1.1.9 匯出資料庫某資料表成 .ods
https://shaurong.blogspot.com/2024/03/aspnetwebform-freedataexports-119-ods_29.html

[研究]ASP.NET,WebForm,用 FreeDataExports 1.1.9 匯出 .ods
https://shaurong.blogspot.com/2024/03/aspnetwebform-freedataexports-119-ods.html

[研究]ASP.NET,WebForm, 把 OdsReadWrite.cs 從 Ionic.Zip 或 DotNetZip 改成用 System.IO.Compression
https://shaurong.blogspot.com/2024/03/aspnetwebform-odsreadwritecs-ioniczip.html

[研究]ASP.NET,WebForm,用 OdsReaderWriter + DotNetZip (Ionic.Zip) 1.16.0 共用匯出 .ods
https://shaurong.blogspot.com/2024/03/aspnetwebform-odsreaderwriter-dotnetzip_79.html

[研究]ASP.NET,WebForm,用 OdsReaderWriter + DotNetZip (Ionic.Zip) 1.16.0 匯出 .ods
https://shaurong.blogspot.com/2024/03/aspnetwebform-odsreaderwriter-dotnetzip_23.html

[研究]ASP.NET,WebForm,用 OdsReaderWriter + DotNetZip (Ionic.Zip) 1.16.0 匯入 .ods
https://shaurong.blogspot.com/2024/03/aspnetwebform-odsreaderwriter-dotnetzip_93.html

How to Read and Write ODF/ODS Files (OpenDocument Spreadsheets) - CodeProject
https://www.codeproject.com/Articles/38425/How-to-Read-and-Write-ODF-ODS-Files-OpenDocument-2

[研究][ASP.NET]讀取、匯出、寫入、匯入 Excel .xlsx .xls ODF .ods
https://shaurong.blogspot.com/2020/04/caspnetwebform-excel-xlsx-xls-odf-ods.html

[研究][ASP.NET]使用 OdsReaderWriter + DotNetZip 1.15.0 (Ionic.Zip) 匯出寫入 .ods
https://shaurong.blogspot.com/2021/02/aspnet-odsreaderwriter-dotnetzip-1150_9.html

[研究][ASP.NET]使用 OdsReaderWriter + DotNetZip 1.15.0 讀取匯入 .ods 到資料庫
https://shaurong.blogspot.com/2021/02/aspnet-odsreaderwriter-dotnetzip-1150.html

[研究][C#]用OdsReaderWrite匯出(寫入)、匯入(讀取) ODF/.ods 檔案 (使用 Ionic.Zip、DotNetZip)
https://shaurong.blogspot.com/2020/09/caspnetwebform-ioniczip-odfods.html

[研究] [C#] 用OdsReadWrite讀取 LibreOffice、OpenOffice 的試算表(Calc) 檔案 (.ods)(使用 .NET 4.5 的 ZipFile)
https://shaurong.blogspot.com/2016/12/c-libreoffice-516-calc-ods-net-45.html

[研究] [C#] 用OdsReaderWrite讀取 LibreOffice 5.1.6 的試算表(Calc) 檔案 (.ods)(使用 DotNetZip)
https://shaurong.blogspot.com/2016/12/c-libreoffice-516-calc-ods.html

NuGet Gallery | OdsReaderWriter 1.0.10
https://www.nuget.org/packages/OdsReaderWriter

sortings/OdsReadWrite at master · Luviz/sortings · GitHub
https://github.com/Luviz/sortings/tree/master/OdsReadWrite




2024年10月29日 星期二

[研究]ASP.NET,WebForm,免ODS套件寫入匯出.ods

[研究]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 並不容易,運氣好是警告,然後可以讀取,運氣不好是完全不能讀取。

(完)

相關

[研究]ASP.NET,WebForm,免ODS套件匯入讀取.ods

[研究]ASP.NET,WebForm,免ODS套件匯入讀取.ods

2024-10-28

環境:Visual Studio 2022 + ASP.NET + WebForm + Web Application + C# + SQL Server 2019 + SQL Server Management Studio (SSMS) 19

********************************************************************************

【免ODS套件讀取.ods】

Default.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" 
    Inherits="WebApplication1.Default" %>

<!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">
        <asp:GridView ID="GridView1" runat="server"></asp:GridView>
    </form>
</body>
</html>



Default.aspx.cs

using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Text;
using System.Xml.Linq;

namespace WebApplication1
{
    public class OdsReader
    {
        public static List<List<string>> ReadOdsFile(string filePath)
        {
            List<List<string>> data = new List<List<string>>();

            using (ZipArchive archive = ZipFile.OpenRead(filePath))
            {
                // 找到 content.xml 檔案
                ZipArchiveEntry contentEntry = archive.GetEntry("content.xml");
                if (contentEntry != null)
                {
                    using (StreamReader reader = new StreamReader(contentEntry.Open(), Encoding.UTF8))
                    {
                        string xmlContent = reader.ReadToEnd();
                        XDocument doc = XDocument.Parse(xmlContent);

                        // 解析 XML 檔案中的資料
                        foreach (var row in doc.Descendants("{urn:oasis:names:tc:opendocument:xmlns:table:}table-row"))
                        {
                            List<string> rowData = new List<string>();
                            foreach (var cell in row.Descendants("{urn:oasis:names:tc:opendocument:xmlns:table:}table-cell"))
                            {
                                string cellValue = cell.Element("{urn:oasis:names:tc:opendocument:xmlns:text:}p")?.Value ?? string.Empty;
                                rowData.Add(cellValue);
                            }
                            data.Add(rowData);
                        }
                    }
                }
            }
            return data;
        }
    }
    public partial class Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                //string filePath = Server.MapPath("~/path/to/your/file.ods");
                string filePath = @"C:\Users\Administrator\Downloads\Sample.ods";
                List<List<string>> odsData = ReadOdsFile(filePath);

                // 將資料綁定到 GridView
                BindGridView(odsData);
            }
        }
        private List<List<string>> ReadOdsFile(string filePath)
        {
            List<List<string>> data = new List<List<string>>();

            using (ZipArchive archive = ZipFile.OpenRead(filePath))
            {
                ZipArchiveEntry contentEntry = archive.GetEntry("content.xml");
                if (contentEntry != null)
                {
                    using (StreamReader reader = new StreamReader(contentEntry.Open(), Encoding.UTF8))
                    {
                        string xmlContent = reader.ReadToEnd();
                        XDocument doc = XDocument.Parse(xmlContent);

                        // 設定 XML 命名空間
                        XNamespace nsTable = "urn:oasis:names:tc:opendocument:xmlns:table:1.0";
                        XNamespace nsText = "urn:oasis:names:tc:opendocument:xmlns:text:1.0";

                        // 解析 table-row 和 table-cell 元素
                        foreach (var row in doc.Descendants(nsTable + "table-row"))
                        {
                            List<string> rowData = new List<string>();
                            foreach (var cell in row.Descendants(nsTable + "table-cell"))
                            {
                                string cellValue = cell.Element(nsText + "p")?.Value ?? string.Empty;
                                rowData.Add(cellValue);
                            }
                            data.Add(rowData);
                        }
                    }
                }
            }

            return data;
        }

        private void BindGridView(List<List<string>> odsData)
        {
            // 將資料轉換為 DataTable
            var dataTable = new System.Data.DataTable();

            // 動態添加列
            for (int i = 0; i < odsData[0].Count; i++)
            {
                dataTable.Columns.Add($"Column{i + 1}");
            }

            // 添加資料行
            foreach (var row in odsData)
            {
                dataTable.Rows.Add(row.ToArray());
            }

            // 綁定資料到 GridView
            GridView1.DataSource = dataTable;
            GridView1.DataBind();
        }
        //---
    }
}



結果

下圖,若 Sample.ods 是 LibreOffice 7.6 建立的

下圖,若 Sample.ods 是 Excel 2021 建立的

其實一開始 ChatGPT 寫的程式完全不能用,後來把 XDocument doc = XDocument.Parse(xmlContent); 讀取到的 doc 丟給 ChatGPT,才改出可以用的程式。不確定此程式通用性多高,doc讀取到內容如下

<?xml version="1.0"?>

+
<office:document-content office:version="1.3"
	xmlns:presentation="urn:oasis:names:tc:opendocument:
	xmlns:presentation:1.0"
	xmlns:css3t="http://www.w3.org/TR/css3-text/"
	xmlns:grddl="http://www.w3.org/2003/g/data-view#"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:xsd="http://www.w3.org/2001/XMLSchema"
	xmlns:dom="http://www.w3.org/2001/xml-events"
	xmlns:formx="urn:openoffice:names:experimental:ooxml-odf-interop:
	xmlns:form:1.0"
	xmlns:script="urn:oasis:names:tc:opendocument:
	xmlns:script:1.0"
	xmlns:form="urn:oasis:names:tc:opendocument:
	xmlns:form:1.0"
	xmlns:math="http://www.w3.org/1998/Math/MathML"
	xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:
	xmlns:field:1.0"
	xmlns:loext="urn:org:documentfoundation:names:experimental:office:
	xmlns:loext:1.0"
	xmlns:xhtml="http://www.w3.org/1999/xhtml"
	xmlns:drawooo="http://openoffice.org/2010/draw"
	xmlns:calcext="urn:org:documentfoundation:names:experimental:calc:
	xmlns:calcext:1.0"
	xmlns:tableooo="http://openoffice.org/2009/table"
	xmlns:xforms="http://www.w3.org/2002/xforms"
	xmlns:of="urn:oasis:names:tc:opendocument:
	xmlns:of:1.2"
	xmlns:oooc="http://openoffice.org/2004/calc"
	xmlns:ooow="http://openoffice.org/2004/writer"
	xmlns:number="urn:oasis:names:tc:opendocument:
	xmlns:datastyle:1.0"
	xmlns:table="urn:oasis:names:tc:opendocument:
	xmlns:table:1.0"
	xmlns:chart="urn:oasis:names:tc:opendocument:
	xmlns:chart:1.0"
	xmlns:svg="urn:oasis:names:tc:opendocument:
	xmlns:svg-compatible:1.0"
	xmlns:dr3d="urn:oasis:names:tc:opendocument:
	xmlns:dr3d:1.0"
	xmlns:draw="urn:oasis:names:tc:opendocument:
	xmlns:drawing:1.0"
	xmlns:rpt="http://openoffice.org/2005/report"
	xmlns:text="urn:oasis:names:tc:opendocument:
	xmlns:text:1.0"
	xmlns:style="urn:oasis:names:tc:opendocument:
	xmlns:style:1.0"
	xmlns:meta="urn:oasis:names:tc:opendocument:
	xmlns:meta:1.0"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:xlink="http://www.w3.org/1999/xlink"
	xmlns:fo="urn:oasis:names:tc:opendocument:
	xmlns:xsl-fo-compatible:1.0"
	xmlns:ooo="http://openoffice.org/2004/office"
	xmlns:office="urn:oasis:names:tc:opendocument:
	xmlns:office:1.0">

(完)

相關

2024年10月28日 星期一

[研究]ASP.NET,WebForm,用 FreeDataExports 1.1.11 匯出 .ods (MIT)

[研究]ASP.NET,WebForm,用 FreeDataExports 1.1.11 匯出 .ods (MIT)

2024-03-29

環境:Visual Studio 2022 + ASP.NET + WebForm + Web Application + C# + SQL Server 2019 + SQL Server Management Studio (SSMS) 19

********************************************************************************

https://www.nuget.org/packages/FreeDataExports/1.1.11/License

授權是 MIT



********************************************************************************

官方網站
https://github.com/ryankueter/FreeDataExports

官方的程式範例有問題。

Web.Config

<?xml version="1.0" encoding="utf-8"?>
<!--
  如需如何設定 ASP.NET 應用程式的詳細資訊,請前往
  https://go.microsoft.com/fwlink/?LinkId=169433
  -->
<configuration>
  <connectionStrings>
    <add name="MyDBConnectionString" connectionString="Data Source=.;Initial Catalog=MyDB;User ID=sa;Password=密碼"
      providerName="System.Data.SqlClient" />
  </connectionStrings>
  <system.web>
    <compilation debug="true" targetFramework="4.8" />
    <httpRuntime targetFramework="4.8" />
  </system.web>
  <system.codedom>
    <compilers>
      <compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:default /nowarn:1659;1699;1701" />
      <compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:default /nowarn:41008 /define:_MYTYPE=\&quot;Web\&quot; /optionInfer+" />
    </compilers>
  </system.codedom>
</configuration>

Default.aspx.cs

using FreeDataExports;

protected void Button1_Click(object sender, EventArgs e)
{
    string path = @"C:\Temp\2.ods";
    var workbook = new DataExport().CreateODSv1_3();
    var worksheet = workbook.AddWorksheet("工作表1");

    string[] customHeaders = { "Column1", "Column2", "Column3" }; // 依需要替換為實際的列名

    // 查詢語句
    string query = "SELECT * FROM [MyDB].[dbo].[MyTable]";

    using (SqlConnection connection = new SqlConnection(
        WebConfigurationManager.ConnectionStrings["MyDBConnectionString"].ConnectionString))
    {
        using (SqlCommand command = new SqlCommand(query, connection))
        {
            using (SqlDataAdapter dataAdapter = new SqlDataAdapter(command))
            {
                DataTable dataTable = new DataTable();
                dataAdapter.Fill(dataTable);

                // 新增自訂標題
                worksheet.AddRow();
                for (int i = 0; i < customHeaders.Length; i++)
                {
                    worksheet.AddCell(customHeaders[i], DataType.String);
                }

                // 匯出資料到.ods文件
                for (int i = 0; i < dataTable.Rows.Count; i++)
                {
                    worksheet.AddRow();
                    for (int j = 0; j < dataTable.Columns.Count; j++)
                        worksheet.AddCell(dataTable.Rows[i].ItemArray[j], DataType.String);
                }
                workbook.Save(path);
            }
        }
    }
}


實際測試可以成功。

********************************************************************************

Default.aspx.cs

protected void Button2_Click(object sender, EventArgs e)
{
    var workbook = new DataExport().CreateODSv1_3();
    var worksheet = workbook.AddWorksheet("工作表1");

    string[] customHeaders = { "Column1", "Column2", "Column3" }; // 依需要替換為實際的列名

    // 查詢語句
    string query = "SELECT * FROM [MyDB].[dbo].[MyTable]";

    using (SqlConnection connection = new SqlConnection(
        WebConfigurationManager.ConnectionStrings["MyDBConnectionString"].ConnectionString))
    {
        using (SqlCommand command = new SqlCommand(query, connection))
        {
            using (SqlDataAdapter dataAdapter = new SqlDataAdapter(command))
            {
                DataTable dataTable = new DataTable();
                dataAdapter.Fill(dataTable);

                // 新增自訂標題
                worksheet.AddRow();
                for (int i = 0; i < customHeaders.Length; i++)
                {
                    worksheet.AddCell(customHeaders[i], DataType.String);
                }

                // 匯出資料到.ods文件
                for (int i = 0; i < dataTable.Rows.Count; i++)
                {
                    worksheet.AddRow();
                    for (int j = 0; j < dataTable.Columns.Count; j++)
                        worksheet.AddCell(dataTable.Rows[i].ItemArray[j], DataType.String);
                }

                // 使用 MemoryStream 將檔案直接下載
                using (MemoryStream stream = new MemoryStream())
                {
                    workbook.Save(stream);
                    stream.Position = 0;

                    // 設定回應頭,讓瀏覽器顯示下載提示
                    Response.Clear();
                    Response.ContentType = "application/vnd.oasis.opendocument.spreadsheet";
                    Response.AddHeader("Content-Disposition", "attachment; filename=ExportedData.ods");
                    Response.BinaryWrite(stream.ToArray());
                    Response.Flush();
                    Response.End();
                }
            }
        }
    }
}

編譯 workbook.Save(stream); 會出錯


個錯誤是因為 Save 方法預期的是一個檔案路徑(字串類型),而不是 MemoryStream。可以檢查 CreateODSv1_3 所使用的類別庫是否支援儲存至 MemoryStream,若無,則需要調整程式碼。

********************************************************************************

【先暫存再彈出,成功】

Default.aspx.cs

protected void Button3_Click(object sender, EventArgs e)
{
    //string tempFilePath = Server.MapPath("~/Temp/ExportedData.ods"); // 暫存檔案路徑
    string tempFilePath = @"C:\temp\ExportedData.ods"; // 暫存檔案路徑
    var workbook = new DataExport().CreateODSv1_3();
    var worksheet = workbook.AddWorksheet("工作表1");

    string[] customHeaders = { "Column1", "Column2", "Column3" }; // 依需要替換為實際的列名

    // 查詢語句
    string query = "SELECT * FROM [MyDB].[dbo].[MyTable]";

    using (SqlConnection connection = new SqlConnection(
        WebConfigurationManager.ConnectionStrings["MyDBConnectionString"].ConnectionString))
    {
        using (SqlCommand command = new SqlCommand(query, connection))
        {
            using (SqlDataAdapter dataAdapter = new SqlDataAdapter(command))
            {
                DataTable dataTable = new DataTable();
                dataAdapter.Fill(dataTable);

                // 新增自訂標題
                worksheet.AddRow();
                for (int i = 0; i < customHeaders.Length; i++)
                {
                    worksheet.AddCell(customHeaders[i], DataType.String);
                }

                // 匯出資料到.ods文件
                for (int i = 0; i < dataTable.Rows.Count; i++)
                {
                    worksheet.AddRow();
                    for (int j = 0; j < dataTable.Columns.Count; j++)
                        worksheet.AddCell(dataTable.Rows[i].ItemArray[j], DataType.String);
                }

                // 儲存至暫存路徑
                workbook.Save(tempFilePath);

                // 讀取檔案內容並下載
                byte[] fileBytes = System.IO.File.ReadAllBytes(tempFilePath);
                Response.Clear();
                Response.ContentType = "application/vnd.oasis.opendocument.spreadsheet";
                Response.AddHeader("Content-Disposition", "attachment; filename=ExportedData.ods");
                Response.BinaryWrite(fileBytes);
                Response.Flush();
                Response.End();

                // 刪除暫存檔案
                System.IO.File.Delete(tempFilePath);
            }
        }
    }
}


********************************************************************************

(完)

相關

[研究]ASP.NET,WebForm,用 FreeDataExports 1.1.11 匯出 .ods
https://shaurong.blogspot.com/2024/10/aspnetwebform-freedataexports-1111-ods.html

[研究]ASP.NET,WebForm,要傳遞 SqlDataSource1.SelectParameters 當時的值https://shaurong.blogspot.com/2024/03/aspnetwebform-sqldatasource1selectparam.html

[研究]ASP.NET,WebForm,用 FreeDataExports 1.1.9 匯出資料庫某資料表成 .ods
https://shaurong.blogspot.com/2024/03/aspnetwebform-freedataexports-119-ods_29.html

[研究]ASP.NET,WebForm,用 FreeDataExports 1.1.9 匯出 .ods
https://shaurong.blogspot.com/2024/03/aspnetwebform-freedataexports-119-ods.html

[研究]ASP.NET,WebForm, 把 OdsReadWrite.cs 從 Ionic.Zip 或 DotNetZip 改成用 System.IO.Compression
https://shaurong.blogspot.com/2024/03/aspnetwebform-odsreadwritecs-ioniczip.html

[研究]ASP.NET,WebForm,用 OdsReaderWriter + DotNetZip (Ionic.Zip) 1.16.0 共用匯出 .ods
https://shaurong.blogspot.com/2024/03/aspnetwebform-odsreaderwriter-dotnetzip_79.html

[研究]ASP.NET,WebForm,用 OdsReaderWriter + DotNetZip (Ionic.Zip) 1.16.0 匯出 .ods
https://shaurong.blogspot.com/2024/03/aspnetwebform-odsreaderwriter-dotnetzip_23.html

[研究]ASP.NET,WebForm,用 OdsReaderWriter + DotNetZip (Ionic.Zip) 1.16.0 匯入 .ods
https://shaurong.blogspot.com/2024/03/aspnetwebform-odsreaderwriter-dotnetzip_93.html

How to Read and Write ODF/ODS Files (OpenDocument Spreadsheets) - CodeProject
https://www.codeproject.com/Articles/38425/How-to-Read-and-Write-ODF-ODS-Files-OpenDocument-2

[研究][ASP.NET]讀取、匯出、寫入、匯入 Excel .xlsx .xls ODF .ods
https://shaurong.blogspot.com/2020/04/caspnetwebform-excel-xlsx-xls-odf-ods.html

[研究][ASP.NET]使用 OdsReaderWriter + DotNetZip 1.15.0 (Ionic.Zip) 匯出寫入 .ods
https://shaurong.blogspot.com/2021/02/aspnet-odsreaderwriter-dotnetzip-1150_9.html

[研究][ASP.NET]使用 OdsReaderWriter + DotNetZip 1.15.0 讀取匯入 .ods 到資料庫
https://shaurong.blogspot.com/2021/02/aspnet-odsreaderwriter-dotnetzip-1150.html

[研究][C#]用OdsReaderWrite匯出(寫入)、匯入(讀取) ODF/.ods 檔案 (使用 Ionic.Zip、DotNetZip)
https://shaurong.blogspot.com/2020/09/caspnetwebform-ioniczip-odfods.html

[研究] [C#] 用OdsReadWrite讀取 LibreOffice、OpenOffice 的試算表(Calc) 檔案 (.ods)(使用 .NET 4.5 的 ZipFile)
https://shaurong.blogspot.com/2016/12/c-libreoffice-516-calc-ods-net-45.html

[研究] [C#] 用OdsReaderWrite讀取 LibreOffice 5.1.6 的試算表(Calc) 檔案 (.ods)(使用 DotNetZip)
https://shaurong.blogspot.com/2016/12/c-libreoffice-516-calc-ods.html

NuGet Gallery | OdsReaderWriter 1.0.10
https://www.nuget.org/packages/OdsReaderWriter

sortings/OdsReadWrite at master · Luviz/sortings · GitHub
https://github.com/Luviz/sortings/tree/master/OdsReadWrite

2024年3月30日 星期六

[研究]ASP.NET,WebForm,用 NuGet OdsReaderWriter 1.0.10 匯出 .ods

[研究]ASP.NET,WebForm,用 NuGet OdsReaderWriter 1.0.10 匯出 .ods

2024-03-30

環境:Visual Studio 2022 + ASP.NET + WebForm + Web Application + C# + SQL Server 2019 + SQL Server Management Studio (SSMS) 19

********************************************************************************

發現 NuGet 提供 OdsReaderWriter 1.0.10,其實源頭也相同是 CodeProject 那篇,但是程式寫法有點不同;也不用自己另外手動安裝 Ionic.Zip 或 DotNetZip,會自動相依安裝。

NuGet Gallery | OdsReaderWriter 1.0.10
https://www.nuget.org/packages/OdsReaderWriter

GitHub - Zaretto/ODSReaderWriter: Open Document Spreadsheet reader writer
https://github.com/Zaretto/ODSReaderWriter
這邊直接下載 Code,敝人用 Visual Studio 2019 直接編譯是不能用。

How to Read and Write ODF/ODS Files (OpenDocument Spreadsheets) - CodeProject
https://www.codeproject.com/Articles/38425/How-to-Read-and-Write-ODF-ODS-Files-OpenDocument-2



WebApplication1

正在安裝:

DotNetZip.Reduced.1.9.1.8

OdsReaderWriter.1.0.10



OdsReaderWriter 1.0.10
GPL-2.0-only

How to Read and Write ODF/ODS Files (OpenDocument Spreadsheets)
This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)
提供 odsreadwrite.zip

註:ChatGPT
The Code Project Open License (CPOL) 是由 The Code Project 社群發布的一種軟體授權。以下是關於 CPOL 的主要重點:
  • 寬鬆的授權:CPOL 允許用戶自由使用、修改和分發軟體,不論是二進位形式還是原始碼形式。
  • 不要求開源:與 GPL 等授權不同,CPOL 不要求衍生作品必須開源。您可以在專有項目中使用 CPOL 授權的代碼,而不必公開自己的原始碼。
  • 歸屬要求(Attribution):在分發軟體或衍生作品時,必須給予原作者適當的歸屬。
  • 免責聲明:該授權通常包括免責聲明,表示軟體是“按原樣”提供的,沒有任何保證。
總結來說,CPOL 允許您在遵守歸屬和免責條款的前提下,自由使用、修改和分發軟體,而無需開源您的代碼。

********************************************************************************

Web.Config

<?xml version="1.0" encoding="utf-8"?>
<!--
  如需如何設定 ASP.NET 應用程式的詳細資訊,請前往
  https://go.microsoft.com/fwlink/?LinkId=169433
  -->
<configuration>
  <connectionStrings>
    <add name="MyDBConnectionString" connectionString="Data Source=127.0.0.1;Initial Catalog=MyDB;User ID=sa;Password=P@ssw0rd"
      providerName="System.Data.SqlClient" />
  </connectionStrings>
  <system.web>
    <compilation debug="true" targetFramework="4.8" />
    <httpRuntime targetFramework="4.8" />
  </system.web>
  <system.codedom>
    <compilers>
      <compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:default /nowarn:1659;1699;1701" />
      <compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:default /nowarn:41008 /define:_MYTYPE=\&quot;Web\&quot; /optionInfer+" />
    </compilers>
  </system.codedom>
  <appSettings>
    <add key="TempFolder" value="D:\Production\TempImageFiles\" />
  </appSettings>
</configuration>


Default.aspx

<%@ Page Language="C#" AutoEventWireup="true"
    CodeBehind="Default.aspx.cs" Inherits="WebApplication2.Default" %>

<!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">
        <asp:SqlDataSource ID="SqlDataSource_Field2" runat="server"
            ConnectionString="<%$ ConnectionStrings:MyDBConnectionString %>"
            SelectCommand="SELECT N'全部' AS [Field2], 0 AS Priority
            UNION
            SELECT DISTINCT [Field2], 1 AS Priority FROM [MyTable] ORDER BY Priority, [Field2]"></asp:SqlDataSource>
        <asp:DropDownList ID="DropDownList_Field2" runat="server"
            AutoPostBack="True" DataSourceID="SqlDataSource_Field2"
            DataTextField="Field2" DataValueField="Field2">
        </asp:DropDownList>
        <br />
        <asp:Button ID="Button_Export_ODS_by_OdsReaderWriter_DotNetZip_IonicZip" runat="server" Text="匯出(.ods)"
            OnClick="Button_Export_ODS_by_OdsReaderWriter_DotNetZip_IonicZip_Click" /><br />
        <asp:Label ID="Label_MSG1" runat="server" Text="Label"></asp:Label>
        <asp:SqlDataSource ID="SqlDataSource1" runat="server"
            ConnectionString="<%$ ConnectionStrings:MyDBConnectionString %>"
            SelectCommand="--TSQL--
            SELECT * FROM [MyTable]
            WHERE ([Field2]=@Field2 OR @Field2=N'全部');">
            <SelectParameters>
                <asp:ControlParameter ControlID="DropDownList_Field2" Name="Field2" PropertyName="SelectedValue" />
            </SelectParameters>
        </asp:SqlDataSource>
        <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="SN" DataSourceID="SqlDataSource1">
            <Columns>
                <asp:BoundField DataField="SN" HeaderText="SN" InsertVisible="False" ReadOnly="True" SortExpression="SN" />
                <asp:BoundField DataField="Field1" HeaderText="Field1" SortExpression="Field1" />
                <asp:BoundField DataField="Field2" HeaderText="Field2" SortExpression="Field2" />
            </Columns>
        </asp:GridView>

    </form>
</body>
</html>



Default.aspx.cs

using System;
using System.Data;
using System.Data.SqlClient;
using System.IO;
using System.Web;
using System.Web.Configuration;
using System.Web.UI;
using Zaretto.ODS;  // NuGet ODSReaderWriter 1.0.10 使用

namespace WebApplication1
{
    public partial class Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }

        //【匯出(.ods)】
        #region === protected void Button_Export_ODS_by_OdsReaderWriter_DotNetZip_IonicZip_Click(object sender, EventArgs e) ===
        protected void Button_Export_ODS_by_OdsReaderWriter_DotNetZip_IonicZip_Click(object sender, EventArgs e)
        {
            // Import
            // https://docs.microsoft.com/en-us/office/open-xml/how-to-parse-and-read-a-large-spreadsheet

            // Export
            // https://docs.microsoft.com/en-us/office/open-xml/how-to-create-a-spreadsheet-document-by-providing-a-file-name

            //Insert text into a cell in a spreadsheet document(Open XML SDK)
            //https://docs.microsoft.com/zh-tw/office/open-xml/how-to-insert-text-into-a-cell-in-a-spreadsheet

            string mainFileName = "匯出檔案名稱";

            // 若檔案名稱有中文字或特殊符號,Response.AddHeader() 輸出檔案名稱要編碼
            string outFileName = HttpUtility.UrlEncode(mainFileName, System.Text.Encoding.UTF8) + "-" +
                DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss-fff") + ".ods";

            // XLWorkbook.SaveAs() 輸出檔案名稱不要用 HttpUtility.UrlEncode 編碼
            // Response.TransmitFile() 輸出檔案名稱不要用 HttpUtility.UrlEncode 編碼
            string dirFileName = @"D:\Production\TempImageFiles\" + mainFileName + "-" +
                DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss-fff") + ".ods";
            try
            {
                Response.Clear();
                Response.Buffer = true;
                Response.Charset = "";

                #region === Export ODS ===

                // [EXCEL] Excel打開是亂碼?快速找回資料的最好方法!
                // http://blog.e-happy.com.tw/excel-excel%E6%89%93%E9%96%8B%E6%98%AF%E4%BA%82%E7%A2%BC%EF%BC%9F%E5%BF%AB%E9%80%9F%E6%89%BE%E5%9B%9E%E8%B3%87%E6%96%99%E7%9A%84%E6%9C%80%E5%A5%BD%E6%96%B9%E6%B3%95%EF%BC%81/

                // Excel開啟CSV時的中文編碼問題補遺
                //https://blog.darkthread.net/blog/csv-encoding-again/

                //Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
                Response.ContentType = "application/vnd.oasis.opendocument.spreadsheet";    // ODF/.ods
                Response.AddHeader("content-disposition", "attachment;filename=" + outFileName);
                using (MemoryStream MyMemoryStream = new MemoryStream())
                {
                    StreamWriter odsFileStreamWriter = new StreamWriter(MyMemoryStream);
                    StreamReader odsFileStreamReader = new StreamReader(new MemoryStream());
                    string dataText = "";

                    DataSet ds = new DataSet("DS1");
                    //DataTable dt = new DataTable();
                    DataTable dt = ds.Tables.Add("工作表1");

                    string[] columnNameArray = {
"流水號"
,"欄位1"
,"欄位2"
        };
                    foreach (string columnName in columnNameArray)
                    {
                        DataColumn dataColumnName = new DataColumn
                        {
                            DataType = System.Type.GetType("System.String"),
                            ColumnName = columnName
                        };
                        dt.Columns.Add(dataColumnName);
                    }

                    DataRow dataColumnNameRow = dt.NewRow();
                    int ii = 0;
                    foreach (string columnName in columnNameArray)
                    {
                        dataColumnNameRow[ii] = columnName;
                        ii++;
                    }
                    dt.Rows.Add(dataColumnNameRow);

                    string queryString = SqlDataSource1.SelectCommand;
                    using (SqlConnection connection = new SqlConnection(WebConfigurationManager.ConnectionStrings["MyDBConnectionString"].ConnectionString))
                    {
                        SqlCommand command = new SqlCommand(queryString, connection);
                        command.Parameters.Clear();
                        command.Parameters.AddWithValue("@Field2", DropDownList_Field2.SelectedValue);
                        connection.Open();

                        //Get All column 
                        //var columnNames = Enumerable.Range(0, reader.FieldCount)
                        //                        .Select(reader.GetName)
                        //                        .ToList();

                        ////Create headers
                        //sb.Append(string.Join(",", columnNames));

                        ////Append Line
                        //sb.AppendLine();

                        try
                        {
                            using (SqlDataReader reader = command.ExecuteReader())
                            {
                                while (reader.Read())
                                {
                                    //Console.WriteLine(String.Format("{0}", reader[0]));
                                    DataRow datarow = dt.NewRow();
                                    for (int i = 0; i < reader.FieldCount; i++)
                                    {
                                        dataText = reader[i].ToString();
                                        // 換掉影響 CSV 顯示效果的字元
                                        dataText = dataText.Replace("\r", "").Replace("\n", "").Replace("\t", "").Replace(",", ",").Replace("'", "′").Replace(@"""", "”");
                                        //if (i > 0)
                                        //{
                                        //    datarow[i - 1] = dataText;
                                        //}
                                        datarow[i] = dataText;
                                        //if (i == 1)
                                        //{
                                        //    //if (csvContent=="")
                                        //    //    csvContent = dataText;
                                        //    //else
                                        //    //csvContent = csvContent + "\r\n" + dataText;
                                        //    csvContent.Append("\r\n" + dataText);

                                        //}
                                        //else
                                        //{
                                        //    //csvContent = csvContent + "," + dataText;
                                        //    csvContent.Append("," + dataText);
                                        //}
                                    }
                                    dt.Rows.Add(datarow);
                                }
                            }

                            //OdsReaderWriter odsFile = new OdsReaderWriter();  // OdsReaderWriter.cs 使用
                            ODSReaderWriter odsFile = new ODSReaderWriter();  // NuGet OdsReaderWriter 使用,注意大小寫不同
                            //odsFile.WriteOdsFile(ds, @"C:\TEMP\1.ods");
                            odsFile.WriteOdsFile(ds, dirFileName);

                            // Write the DataSet directly to the MemoryStream
                            // 格式有問題,WriteOdsFile 可能有對 ds (DataSet) 再處理,
                            // 所以此處直接以 Xml 寫入 MyMemoryStream 是不行的
                            //ds.WriteXml(MyMemoryStream);

                            Label_MSG1.ForeColor = System.Drawing.Color.Green;
                            string msg = DateTime.Now.ToString() + "匯出成功。";
                            Label_MSG1.Text = msg;
                            Page.ClientScript.RegisterStartupScript(Page.GetType(), "message", "<script language='javascript' defer>alert('" + msg + "');</script>");
                        }
                        catch (Exception)
                        {
                            throw;
                        }
                    }
                    Response.TransmitFile(dirFileName);
                    Response.End();

                    // Transmit the file directly without saving to server
                    //MyMemoryStream.Position = 0;
                    //MyMemoryStream.CopyTo(Response.OutputStream);
                }
                #endregion Export ODS
            }
            catch (Exception)
            {
                throw;
            }
            Page.ClientScript.RegisterStartupScript(Page.GetType(), "message", "<script language='javascript' defer>alert('匯出成功。');</script>");
        }
        #endregion
    }
}


實際測試可以成功。

(完)

相關

[研究]ASP.NET,WebForm,用 NuGet OdsReaderWriter 1.0.10 匯出 .ods
https://shaurong.blogspot.com/2024/03/aspnetwebform-nuget-odsreaderwriter.html

[研究]ASP.NET,WebForm, 把 OdsReadWrite.cs 從 Ionic.Zip 或 DotNetZip 改成用 System.IO.Compression
https://shaurong.blogspot.com/2024/03/aspnetwebform-odsreadwritecs-ioniczip.html

[研究]ASP.NET,WebForm,用 OdsReaderWriter + DotNetZip (Ionic.Zip) 1.16.0 共用匯出 .ods
https://shaurong.blogspot.com/2024/03/aspnetwebform-odsreaderwriter-dotnetzip_79.html

[研究]ASP.NET,WebForm,用 OdsReaderWriter + DotNetZip (Ionic.Zip) 1.16.0 匯出 .ods
https://shaurong.blogspot.com/2024/03/aspnetwebform-odsreaderwriter-dotnetzip_23.html

[研究]ASP.NET,WebForm,用 OdsReaderWriter + DotNetZip (Ionic.Zip) 1.16.0 匯入 .ods
https://shaurong.blogspot.com/2024/03/aspnetwebform-odsreaderwriter-dotnetzip_93.html

How to Read and Write ODF/ODS Files (OpenDocument Spreadsheets) - CodeProject
https://www.codeproject.com/Articles/38425/How-to-Read-and-Write-ODF-ODS-Files-OpenDocument-2

[研究][ASP.NET]讀取、匯出、寫入、匯入 Excel .xlsx .xls ODF .ods
https://shaurong.blogspot.com/2020/04/caspnetwebform-excel-xlsx-xls-odf-ods.html

[研究][ASP.NET]使用 OdsReaderWriter + DotNetZip 1.15.0 (Ionic.Zip) 匯出寫入 .ods
https://shaurong.blogspot.com/2021/02/aspnet-odsreaderwriter-dotnetzip-1150_9.html

[研究][ASP.NET]使用 OdsReaderWriter + DotNetZip 1.15.0 讀取匯入 .ods 到資料庫
https://shaurong.blogspot.com/2021/02/aspnet-odsreaderwriter-dotnetzip-1150.html

[研究][C#]用OdsReaderWrite匯出(寫入)、匯入(讀取) ODF/.ods 檔案 (使用 Ionic.Zip、DotNetZip)
https://shaurong.blogspot.com/2020/09/caspnetwebform-ioniczip-odfods.html

[研究] [C#] 用OdsReadWrite讀取 LibreOffice、OpenOffice 的試算表(Calc) 檔案 (.ods)(使用 .NET 4.5 的 ZipFile)
https://shaurong.blogspot.com/2016/12/c-libreoffice-516-calc-ods-net-45.html

[研究] [C#] 用OdsReaderWrite讀取 LibreOffice 5.1.6 的試算表(Calc) 檔案 (.ods)(使用 DotNetZip)
https://shaurong.blogspot.com/2016/12/c-libreoffice-516-calc-ods.html

NuGet Gallery | OdsReaderWriter 1.0.10
https://www.nuget.org/packages/OdsReaderWriter

sortings/OdsReadWrite at master · Luviz/sortings · GitHub
https://github.com/Luviz/sortings/tree/master/OdsReadWrite








2024年3月29日 星期五

[研究]ASP.NET,WebForm,用 FreeDataExports 1.1.9 匯出資料庫某資料表成 .ods

[研究]ASP.NET,WebForm,用 FreeDataExports 1.1.9 匯出資料庫某資料表成 .ods

2024-03-29

環境:Visual Studio 2022 + ASP.NET + WebForm + Web Application + C# + SQL Server 2019 + SQL Server Management Studio (SSMS) 19

********************************************************************************

官方網站
https://github.com/ryankueter/FreeDataExports

官方的程式範例有問題。

Default.aspx.cs

protected void Button1_Click(object sender, EventArgs e)
{
    string path = @"C:\Temp\2.ods";
    var workbook = new DataExport().CreateODSv1_3();
    var worksheet = workbook.AddWorksheet("工作表1");

    string[] customHeaders = { "Column1", "Column2", "Column3" }; // 依需要替換為實際的列名

    // 查詢語句
    string query = "SELECT * FROM [MyDB].[dbo].[MyTable]";

    using (SqlConnection connection = new SqlConnection(
        WebConfigurationManager.ConnectionStrings["MyDBConnectionString"].ConnectionString))
    {
        using (SqlCommand command = new SqlCommand(query, connection))
        {
            using (SqlDataAdapter dataAdapter = new SqlDataAdapter(command))
            {
                DataTable dataTable = new DataTable();
                dataAdapter.Fill(dataTable);

                // 新增自訂標題
                worksheet.AddRow();
                for (int i = 0; i < customHeaders.Length; i++)
                {
                    worksheet.AddCell(customHeaders[i], DataType.String);
                }

                // 匯出資料到.ods文件
                for (int i = 0; i < dataTable.Rows.Count; i++)
                {
                    worksheet.AddRow();
                    for (int j = 0; j < dataTable.Columns.Count; j++)
                        worksheet.AddCell(dataTable.Rows[i].ItemArray[j], DataType.String);
                }
                workbook.Save(path);
            
                    string exportFilename = "匯出檔案名稱.ods";
                        // 設定回應的標頭資訊
                        Response.Clear();
                        Response.ContentType = "application/vnd.oasis.opendocument.spreadsheet";
                        Response.AddHeader("Content-Disposition", "attachment; filename=" + exportFilename);
                        //Response.BinaryWrite(ms);
                        //Response.BinaryWrite(workbookBytes);
                        Response.TransmitFile(path);
                        Response.End();
            }
        }
    }
}


實際測試可以成功。

(完)

相關

[研究]ASP.NET,WebForm,要傳遞 SqlDataSource1.SelectParameters 當時的值https://shaurong.blogspot.com/2024/03/aspnetwebform-sqldatasource1selectparam.html

[研究]ASP.NET,WebForm,用 FreeDataExports 1.1.9 匯出資料庫某資料表成 .ods
https://shaurong.blogspot.com/2024/03/aspnetwebform-freedataexports-119-ods_29.html

[研究]ASP.NET,WebForm,用 FreeDataExports 1.1.9 匯出 .ods
https://shaurong.blogspot.com/2024/03/aspnetwebform-freedataexports-119-ods.html

[研究]ASP.NET,WebForm, 把 OdsReadWrite.cs 從 Ionic.Zip 或 DotNetZip 改成用 System.IO.Compression
https://shaurong.blogspot.com/2024/03/aspnetwebform-odsreadwritecs-ioniczip.html

[研究]ASP.NET,WebForm,用 OdsReaderWriter + DotNetZip (Ionic.Zip) 1.16.0 共用匯出 .ods
https://shaurong.blogspot.com/2024/03/aspnetwebform-odsreaderwriter-dotnetzip_79.html

[研究]ASP.NET,WebForm,用 OdsReaderWriter + DotNetZip (Ionic.Zip) 1.16.0 匯出 .ods
https://shaurong.blogspot.com/2024/03/aspnetwebform-odsreaderwriter-dotnetzip_23.html

[研究]ASP.NET,WebForm,用 OdsReaderWriter + DotNetZip (Ionic.Zip) 1.16.0 匯入 .ods
https://shaurong.blogspot.com/2024/03/aspnetwebform-odsreaderwriter-dotnetzip_93.html

How to Read and Write ODF/ODS Files (OpenDocument Spreadsheets) - CodeProject
https://www.codeproject.com/Articles/38425/How-to-Read-and-Write-ODF-ODS-Files-OpenDocument-2

[研究][ASP.NET]讀取、匯出、寫入、匯入 Excel .xlsx .xls ODF .ods
https://shaurong.blogspot.com/2020/04/caspnetwebform-excel-xlsx-xls-odf-ods.html

[研究][ASP.NET]使用 OdsReaderWriter + DotNetZip 1.15.0 (Ionic.Zip) 匯出寫入 .ods
https://shaurong.blogspot.com/2021/02/aspnet-odsreaderwriter-dotnetzip-1150_9.html

[研究][ASP.NET]使用 OdsReaderWriter + DotNetZip 1.15.0 讀取匯入 .ods 到資料庫
https://shaurong.blogspot.com/2021/02/aspnet-odsreaderwriter-dotnetzip-1150.html

[研究][C#]用OdsReaderWrite匯出(寫入)、匯入(讀取) ODF/.ods 檔案 (使用 Ionic.Zip、DotNetZip)
https://shaurong.blogspot.com/2020/09/caspnetwebform-ioniczip-odfods.html

[研究] [C#] 用OdsReadWrite讀取 LibreOffice、OpenOffice 的試算表(Calc) 檔案 (.ods)(使用 .NET 4.5 的 ZipFile)
https://shaurong.blogspot.com/2016/12/c-libreoffice-516-calc-ods-net-45.html

[研究] [C#] 用OdsReaderWrite讀取 LibreOffice 5.1.6 的試算表(Calc) 檔案 (.ods)(使用 DotNetZip)
https://shaurong.blogspot.com/2016/12/c-libreoffice-516-calc-ods.html

NuGet Gallery | OdsReaderWriter 1.0.10
https://www.nuget.org/packages/OdsReaderWriter

sortings/OdsReadWrite at master · Luviz/sortings · GitHub
https://github.com/Luviz/sortings/tree/master/OdsReadWrite

[研究]ASP.NET,WebForm,用 FreeDataExports 1.1.9 匯出 .ods

[研究]ASP.NET,WebForm,用 FreeDataExports 1.1.9 匯出 .ods

2024-03-29

環境:Visual Studio 2022 + ASP.NET + WebForm + Web Application + C# + SQL Server 2019 + SQL Server Management Studio (SSMS) 19

********************************************************************************

官方網站
https://github.com/ryankueter/FreeDataExports

官方的程式範例有問題,本篇測試使用時修正修改過。

Default.aspx

<%@ Page Async="true" Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication1.Default" %>

<!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">
        <asp:Button ID="Button1" runat="server" Text="匯出(.ods)" OnClick="Button_Export_ODS_by_FeeeDataExports_Click" />
        <asp:Button ID="Button2" runat="server" Text="匯出(.ods)" OnClick="Button_Export_ODS_by_FeeeDataExports2_Click" />
    </form>
</body>
</html>



Default.aspx.cs

using FreeDataExports;
using System;

namespace WebApplication1
{
    public partial class Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }

        #region === protected void Button_Export_ODS_by_FeeeDataExports_Click(object sender, EventArgs e) ===
        protected async void Button_Export_ODS_by_FeeeDataExports_Click(object sender, EventArgs e)
        {
            // https://github.com/ryankueter/FreeDataExports

            string path = @"C:\Temp\1.ods";

            // Create a new workbook
            var workbook = new DataExport().CreateODSv1_3();

            // Optional - Add some metadata
            workbook.CreatedBy = "Jane Doe";

            // Optional - Change the font size
            workbook.FontSize = 11;

            // Create worksheets
            var orders = workbook.AddWorksheet("Orders");
            var inventory = workbook.AddWorksheet("Inventory");

            // Add column titles
            orders.AddRow()
                .AddCell("OrderId", DataType.String)
                .AddCell("Item", DataType.String)
                .AddCell("Units", DataType.String)
                .AddCell("Price", DataType.String)
                .AddCell("OrderDate", DataType.String)
                .AddCell("SalesAssoc", DataType.String)
                .AddCell("Delivered", DataType.String);

            // Add data
            //foreach (var o in orders)
            //{
            //    orders.AddRow()
            //        .AddCell(o.OrderId, DataType.Number)
            //        .AddCell(o.Item, DataType.String)
            //        .AddCell(o.Units, DataType.Number)
            //        .AddCell(o.Price, DataType.Currency)
            //        .AddCell(o.OrderDate, DataType.LongDate)
            //        .AddCell(o.SalesAssociate, DataType.String)
            //        .AddCell(o.Delivered, DataType.Boolean);
            //}

            // Add data directly without foreach loop
            orders.AddRow()
                .AddCell("12345", DataType.Number)
                .AddCell("Product A", DataType.String)
                .AddCell(10, DataType.Number)
                .AddCell(100.50, DataType.Currency)
                .AddCell(DateTime.Now, DataType.LongDate)
                .AddCell("John Doe", DataType.String)
                .AddCell(true, DataType.Boolean);

            // Add column titles
            inventory.AddRow()
                .AddCell("ItemId", DataType.String)
                .AddCell("Item", DataType.String)
                .AddCell("Number", DataType.String)
                .AddCell("Price", DataType.String);

            // Add data
            //foreach (var i in inventory)
            //{
            //	inventory.AddRow()
            //		.AddCell(i.ItemId, DataType.Number)
            //		.AddCell(i.Item, DataType.String)
            //		.AddCell(i.Number, DataType.Number)
            //		.AddCell(i.Price, DataType.Currency);
            //}

            // Optional - Format the tab color in Hexadecimal
            orders.TabColor = "#00FF00"; // Green
            inventory.TabColor = "#0000FF"; // Blue

            // Optional - Add column widths in inches or centimeters (Specify the unit of measure)
            orders.ColumnWidths(".8in", "1in", ".5in", "1in", "1.5in", "1in", "1in");
            inventory.ColumnWidths(".8in", "1in", ".8in", "1in");

            // Optional - Reformat the datatypes
            workbook.Format(DataType.Decimal, "decimals=8");
            workbook.Format(DataType.Currency, "symbol=$,language=en,country=US,decimals=2");

            // Optional - Add a worksheet to display data type conversion errors, only if they occur
            workbook.AddErrorsWorksheet();

            // Optional - Get the error manually
            workbook.GetErrors();

            // Synchronous GetBytes method
            workbook.GetBytes();

            // Asynchronous GetBytes method
            await workbook.GetBytesAsync();

            // Synchronous save method
            workbook.Save(path);

            // Asynchronous save method
            await workbook.SaveAsync(path);
        }
        #endregion === protected void Button_Export_ODS_by_FeeeDataExports_Click(object sender, EventArgs e) ===

        #region === protected void Button_Export_ODS_by_FeeeDataExports2_Click(object sender, EventArgs e) ===
        protected void Button_Export_ODS_by_FeeeDataExports2_Click(object sender, EventArgs e)
        {
            // https://github.com/ryankueter/FreeDataExports

            string path = @"C:\Temp\1.ods";
            var workbook = new DataExport().CreateODSv1_3();
            var orders = workbook.AddWorksheet("Orders");

            // Add column titles
            orders.AddRow()
                .AddCell("OrderId", DataType.String)
                .AddCell("Item", DataType.String)
                .AddCell("Units", DataType.String)
                .AddCell("Price", DataType.String)
                .AddCell("OrderDate", DataType.String)
                .AddCell("SalesAssoc", DataType.String)
                .AddCell("Delivered", DataType.String);

            orders.AddRow()
                .AddCell("12345", DataType.Number)
                .AddCell("Product A", DataType.String)
                .AddCell(10, DataType.Number)
                .AddCell(100.50, DataType.Currency)
                .AddCell(DateTime.Now, DataType.LongDate)
                .AddCell("John Doe", DataType.String)
                .AddCell(true, DataType.Boolean);

            workbook.Save(path);
                    string exportFilename = "匯出檔案名稱.ods";
                        // 設定回應的標頭資訊
                        Response.Clear();
                        Response.ContentType = "application/vnd.oasis.opendocument.spreadsheet";
                        Response.AddHeader("Content-Disposition", "attachment; filename=" + exportFilename);
                        //Response.BinaryWrite(ms);
                        //Response.BinaryWrite(workbookBytes);
                        Response.TransmitFile(path);
                        Response.End();
} #endregion === protected void Button_Export_ODS_by_FeeeDataExports2_Click(object sender, EventArgs e) === } }

實際測試可以成功匯入。








(完)

相關

[研究]ASP.NET,WebForm,要傳遞 SqlDataSource1.SelectParameters 當時的值https://shaurong.blogspot.com/2024/03/aspnetwebform-sqldatasource1selectparam.html

[研究]ASP.NET,WebForm,用 FreeDataExports 1.1.9 匯出資料庫某資料表成 .ods
https://shaurong.blogspot.com/2024/03/aspnetwebform-freedataexports-119-ods_29.html

[研究]ASP.NET,WebForm,用 FreeDataExports 1.1.9 匯出 .ods
https://shaurong.blogspot.com/2024/03/aspnetwebform-freedataexports-119-ods.html

[研究]ASP.NET,WebForm, 把 OdsReadWrite.cs 從 Ionic.Zip 或 DotNetZip 改成用 System.IO.Compression
https://shaurong.blogspot.com/2024/03/aspnetwebform-odsreadwritecs-ioniczip.html

[研究]ASP.NET,WebForm,用 OdsReaderWriter + DotNetZip (Ionic.Zip) 1.16.0 共用匯出 .ods
https://shaurong.blogspot.com/2024/03/aspnetwebform-odsreaderwriter-dotnetzip_79.html

[研究]ASP.NET,WebForm,用 OdsReaderWriter + DotNetZip (Ionic.Zip) 1.16.0 匯出 .ods
https://shaurong.blogspot.com/2024/03/aspnetwebform-odsreaderwriter-dotnetzip_23.html

[研究]ASP.NET,WebForm,用 OdsReaderWriter + DotNetZip (Ionic.Zip) 1.16.0 匯入 .ods
https://shaurong.blogspot.com/2024/03/aspnetwebform-odsreaderwriter-dotnetzip_93.html

How to Read and Write ODF/ODS Files (OpenDocument Spreadsheets) - CodeProject
https://www.codeproject.com/Articles/38425/How-to-Read-and-Write-ODF-ODS-Files-OpenDocument-2

[研究][ASP.NET]讀取、匯出、寫入、匯入 Excel .xlsx .xls ODF .ods
https://shaurong.blogspot.com/2020/04/caspnetwebform-excel-xlsx-xls-odf-ods.html

[研究][ASP.NET]使用 OdsReaderWriter + DotNetZip 1.15.0 (Ionic.Zip) 匯出寫入 .ods
https://shaurong.blogspot.com/2021/02/aspnet-odsreaderwriter-dotnetzip-1150_9.html

[研究][ASP.NET]使用 OdsReaderWriter + DotNetZip 1.15.0 讀取匯入 .ods 到資料庫
https://shaurong.blogspot.com/2021/02/aspnet-odsreaderwriter-dotnetzip-1150.html

[研究][C#]用OdsReaderWrite匯出(寫入)、匯入(讀取) ODF/.ods 檔案 (使用 Ionic.Zip、DotNetZip)
https://shaurong.blogspot.com/2020/09/caspnetwebform-ioniczip-odfods.html

[研究] [C#] 用OdsReadWrite讀取 LibreOffice、OpenOffice 的試算表(Calc) 檔案 (.ods)(使用 .NET 4.5 的 ZipFile)
https://shaurong.blogspot.com/2016/12/c-libreoffice-516-calc-ods-net-45.html

[研究] [C#] 用OdsReaderWrite讀取 LibreOffice 5.1.6 的試算表(Calc) 檔案 (.ods)(使用 DotNetZip)
https://shaurong.blogspot.com/2016/12/c-libreoffice-516-calc-ods.html

NuGet Gallery | OdsReaderWriter 1.0.10
https://www.nuget.org/packages/OdsReaderWriter

sortings/OdsReadWrite at master · Luviz/sortings · GitHub
https://github.com/Luviz/sortings/tree/master/OdsReadWrite