2024年3月31日 星期日

[研究][BAT, PowerShell]顯示Windows Defender版本 (Windows 10、Windows Server 2019)

[研究][BAT, PowerShell]顯示Windows Defender版本 (Windows 10、Windows Server 2019)

2024-03-31

Windows 10

C:\>Reg Query "HKLM\SOFTWARE\Microsoft\Windows Defender\Signature Updates" /v EngineVersion

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Signature Updates
    EngineVersion    REG_SZ    1.1.24020.9


C:\>Reg Query "HKLM\SOFTWARE\Microsoft\Windows Defender\Signature Updates" /v AVSignatureVersion

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Signature Updates
    AVSignatureVersion    REG_SZ    1.407.837.0


C:\>Reg Query "HKLM\SOFTWARE\Microsoft\Windows Defender\Signature Updates" /v SignaturesLastUpdated

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Signature Updates
    SignaturesLastUpdated    REG_BINARY    4053753C1483DA01


C:\>

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

Windows Server 2019

C:\>Reg Query "HKLM\SOFTWARE\Microsoft\Windows Defender\Signature Updates" /v EngineVersion

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Signature Updates
    EngineVersion    REG_SZ    1.1.24020.9


C:\>Reg Query "HKLM\SOFTWARE\Microsoft\Windows Defender\Signature Updates" /v AVSignatureVersion

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Signature Updates
    AVSignatureVersion    REG_SZ    1.407.860.0


C:\>Reg Query "HKLM\SOFTWARE\Microsoft\Windows Defender\Signature Updates" /v SignaturesLastUpdated

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Signature Updates
    SignaturesLastUpdated    REG_BINARY    78BCCB9FC083DA01


C:\>

AVSignatureVersion 代表 Windows Defender 的病毒定義版本。這是防毒引擎用來檢測惡意軟件的簽名文件版本號碼。


Windows Server 2019

C:\>Reg Query "HKLM\SOFTWARE\Microsoft\Windows Defender"

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender
    ProductAppDataPath    REG_SZ    C:\ProgramData\Microsoft\Windows Defender
    ProductLocalizedName    REG_EXPAND_SZ    @%ProgramFiles%\Windows Defender\EppManifest.dll,-1000
    ProductType    REG_DWORD    0x2
    InstallTime    REG_BINARY    76AD4B991B87D601
    InstallLocation    REG_SZ    C:\ProgramData\Microsoft\Windows Defender\Platform\4.18.24020.7-0\
    ProductStatus    REG_DWORD    0x0
    OOBEInstallTime    REG_BINARY    CB846CC81B87D601
    ManagedDefenderProductType    REG_DWORD    0x0
    DisableAntiSpyware    REG_DWORD    0x0
    DisableAntiVirus    REG_DWORD    0x0
    BackupLocation    REG_SZ    C:\ProgramData\Microsoft\Windows Defender\Platform\4.18.24010.12-0
    HybridModeEnabled    REG_DWORD    0x0
    VerifiedAndReputableTrustModeEnabled    REG_DWORD    0x0
    RpcServerUseEndpointMapper    REG_DWORD    0x0
    IsServiceRunning    REG_DWORD    0x1

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\CoreService
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Device Control
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Diagnostics
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\DLP Configs
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\DLP Websites
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Exclusions
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Features
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Miscellaneous Configuration
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\MpEngine
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\MpWatchDog
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\NIS
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Quarantine
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Real-Time Protection
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Remediation
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Reporting
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Scan
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Signature Updates
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Spynet
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Threats
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\UX Configuration
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\WCOS
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Defender\Windows Defender Exploit Guard

C:\>


Windows Server 2019 PowerShell

Windows PowerShell
著作權 (C) Microsoft Corporation. 著作權所有,並保留一切權利。

PS C:\Users\Administrator> Get-MpComputerStatus


AMEngineVersion                  : 1.1.24020.9
AMProductVersion                 : 4.18.24020.7
AMRunningMode                    : Normal
AMServiceEnabled                 : True
AMServiceVersion                 : 4.18.24020.7
AntispywareEnabled               : True
AntispywareSignatureAge          : 0
AntispywareSignatureLastUpdated  : 2024/4/1 上午 01:20:29
AntispywareSignatureVersion      : 1.407.860.0
AntivirusEnabled                 : True
AntivirusSignatureAge            : 0
AntivirusSignatureLastUpdated    : 2024/4/1 上午 01:20:28
AntivirusSignatureVersion        : 1.407.860.0
BehaviorMonitorEnabled           : True
ComputerID                       : C52B17C8-3C04-443F-B2D2-E2B3242BA540
ComputerState                    : 0
DefenderSignaturesOutOfDate      : False
DeviceControlDefaultEnforcement  :
DeviceControlPoliciesLastUpdated : 2023/3/27 上午 08:00:13
DeviceControlState               : Disabled
FullScanAge                      : 4294967295
FullScanEndTime                  :
FullScanOverdue                  : False
FullScanRequired                 : False
FullScanSignatureVersion         :
FullScanStartTime                :
InitializationProgress           : ServiceStartedSuccessfully
IoavProtectionEnabled            : True
IsTamperProtected                : False
IsVirtualMachine                 : False
LastFullScanSource               : 0
LastQuickScanSource              : 2
NISEnabled                       : True
NISEngineVersion                 : 1.1.24020.9
NISSignatureAge                  : 0
NISSignatureLastUpdated          : 2024/4/1 上午 01:20:28
NISSignatureVersion              : 1.407.860.0
OnAccessProtectionEnabled        : True
ProductStatus                    : 524288
QuickScanAge                     : 0
QuickScanEndTime                 : 2024/4/1 上午 06:31:50
QuickScanOverdue                 : False
QuickScanSignatureVersion        : 1.407.844.0
QuickScanStartTime               : 2024/4/1 上午 05:43:45
RealTimeProtectionEnabled        : True
RealTimeScanDirection            : 0
RebootRequired                   : False
SmartAppControlExpiration        :
SmartAppControlState             : Off
TamperProtectionSource           : N/A
TDTCapable                       : N/A
TDTMode                          : N/A
TDTSiloType                      : N/A
TDTStatus                        : N/A
TDTTelemetry                     : N/A
TroubleShootingDailyMaxQuota     :
TroubleShootingDailyQuotaLeft    :
TroubleShootingEndTime           :
TroubleShootingExpirationLeft    :
TroubleShootingMode              :
TroubleShootingModeSource        :
TroubleShootingQuotaResetTime    :
TroubleShootingStartTime         :
PSComputerName                   :



PS C:\Users\Administrator>



以下是各個參數的縮寫以及它們的意義:

1. AMEngineVersion

縮寫:AM 代表 AntiMalware(反惡意軟件)。

意義:這是 Microsoft Defender 反惡意軟件引擎的版本號,負責惡意軟件偵測和掃描。

2. AMProductVersion

縮寫:AM 代表 AntiMalware(反惡意軟件)。

意義:這是 Microsoft Defender 反惡意軟件產品的版本號,表示產品整體的版本資訊。

3. AMServiceVersion

縮寫:AM 代表 AntiMalware(反惡意軟件)。

意義:這是 Microsoft Defender 反惡意軟件服務的版本號,與產品相關的後台服務元件版本。

4. AntispywareSignatureVersion

縮寫:Antispyware 指的是AntiSpyware(反間諜軟件)。

意義:這是 反間諜軟件簽名檔版本,專門用來偵測和防止間諜軟件。

5. AntivirusSignatureVersion

縮寫:Antivirus 指的是AntiVirus(防毒軟件)。

意義:這是 防毒簽名檔版本,用來偵測和防禦已知的病毒和惡意軟件。

6. FullScanSignatureVersion

縮寫:FullScan 指的是Full Scan(完整掃描)。

意義:這是執行 完整系統掃描時使用的簽名檔版本,針對所有文件進行深入掃描。

7. NISEngineVersion

縮寫:NIS 代表 Network Inspection System(網路檢查系統)。

意義:這是 網路檢查系統引擎的版本號,負責檢測網路層面的惡意攻擊或威脅。

8. NISSignatureVersion

縮寫:NIS 代表 Network Inspection System(網路檢查系統)。

意義:這是 網路檢查系統簽名檔版本,用來偵測和防禦來自網路的威脅。

9. QuickScanSignatureVersion

縮寫:QuickScan 指的是Quick Scan(快速掃描)。

意義:這是執行 快速掃描時使用的簽名檔版本,僅檢查系統中常見的威脅入口(例如記憶體和關鍵系統文件)。

(完)

相關

[研究][BAT]顯示作業系統版本資訊

[研究][BAT]顯示作業系統版本資訊

2024-03-31

C:\>reg query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion" /v ProductName

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion
    ProductName    REG_SZ    Windows 10 Pro


C:\>REG Query "HKLM\Software\Microsoft\Windows NT\CurrentVersion" /V DisplayVersion

HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion
    DisplayVersion    REG_SZ    23H2


C:\>REG Query "HKLM\Software\Microsoft\Windows NT\CurrentVersion" /V ReleaseId

HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion
    ReleaseId    REG_SZ    2009


C:\>REG Query "HKLM\Software\Microsoft\Windows NT\CurrentVersion" /V CSDVersion


錯誤: 系統找不到指定的登錄機碼或值。

C:\>Reg Query "HKLM\Software\Microsoft\Windows NT\CurrentVersion" /v BuildLabEx

HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion
    BuildLabEx    REG_SZ    22621.1.amd64fre.ni_release.220506-1250


C:\>ver

Microsoft Windows [版本 10.0.22631.3296]

C:\>


PowerShell

Windows PowerShell
著作權(C) Microsoft Corporation。保留擁有權利。

安裝最新的 PowerShell 以取得新功能和改進功能!https://aka.ms/PSWindows

PS C:\Users\user1> Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion" -Name ProductName


ProductName  : Windows 10 Pro
PSPath       : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion
PSParentPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT
PSChildName  : CurrentVersion
PSDrive      : HKLM
PSProvider   : Microsoft.PowerShell.Core\Registry



PS C:\Users\user1> 

(完)

相關

[研究][BAT]顯示本機MAC address值

[研究][BAT]顯示本機MAC address值

2024-03-31

環境:Windows 10

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

Windows 11繁體中文版上

Microsoft Windows [版本 10.0.22631.3296]
(c) Microsoft Corporation. 著作權所有,並保留一切權利。

C:\Users\user1>ipconfig /all

Windows IP 設定

   主機名稱 . . . . . . . . . . . . .: WIN11NB
   主要 DNS 尾碼  . . . . . . . . . .:
   節點類型 . . . . . . . . . . . . .: 混合式
   IP 路由啟用 . . . . . . . . . . . : 否
   WINS Proxy 啟用 . . . . . . . . . : 否

乙太網路卡 乙太網路:

   媒體狀態 . . . . . . . . . . . . .: 媒體已中斷連線
   連線特定 DNS 尾碼 . . . . . . . . :
   描述 . . . . . . . . . . . . . . .: Intel(R) Ethernet Connection (10) I219-V
   實體位址 . . . . . . . . . . . . .: 68-45-F1-91-AF-0D
   DHCP 已啟用 . . . . . . . . . . . : 是
   自動設定啟用 . . . . . . . . . . .: 是

無線區域網路介面卡 區域連線* 1:

   媒體狀態 . . . . . . . . . . . . .: 媒體已中斷連線
   連線特定 DNS 尾碼 . . . . . . . . :
   描述 . . . . . . . . . . . . . . .: Microsoft Wi-Fi Direct Virtual Adapter
   實體位址 . . . . . . . . . . . . .: 34-CF-F6-FA-BE-4C
   DHCP 已啟用 . . . . . . . . . . . : 是
   自動設定啟用 . . . . . . . . . . .: 是

無線區域網路介面卡 Wi-Fi:

   連線特定 DNS 尾碼 . . . . . . . . :
   描述 . . . . . . . . . . . . . . .: Intel(R) Wi-Fi 6 AX200 160MHz
   實體位址 . . . . . . . . . . . . .: 34-CF-F6-FA-BE-4B
   DHCP 已啟用 . . . . . . . . . . . : 是
   自動設定啟用 . . . . . . . . . . .: 是
   IPv4 位址 . . . . . . . . . . . . : 192.168.1.110(偏好選項)
   子網路遮罩 . . . . . . . . . . . .: 255.255.255.0
   租用取得 . . . . . . . . . . . . .: 2024年3月27日 下午 05:44:33
   租用到期 . . . . . . . . . . . . .: 2024年4月1日 上午 08:56:02
   預設閘道 . . . . . . . . . . . . .: 192.168.1.1
   DHCP 伺服器 . . . . . . . . . . . : 192.168.1.1
   DNS 伺服器 . . . . . . . . . . . .: 192.168.1.1
   NetBIOS over Tcpip . . . . . . . .: 啟用

乙太網路卡 藍牙網路連線:

   媒體狀態 . . . . . . . . . . . . .: 媒體已中斷連線
   連線特定 DNS 尾碼 . . . . . . . . :
   描述 . . . . . . . . . . . . . . .: Bluetooth Device (Personal Area Network)
   實體位址 . . . . . . . . . . . . .: 34-CF-F6-FA-BE-4F
   DHCP 已啟用 . . . . . . . . . . . : 是
   自動設定啟用 . . . . . . . . . . .: 是

C:\Users\user1>


show_mac.bat  
@echo off @rem 英文版 Windows for /f "tokens=2 delims=:" %%i in ('ipconfig /all ^| findstr "Physical Address"') do ( echo Local MAC Address: %%i ) @rem Windows 10 繁體中文版 for /f "tokens=2 delims=:" %%i in ('ipconfig /all ^| findstr "實體位址"') do ( echo 本機 MAC 地址: %%i ) pause


注意:請用【記事本】或支援存檔時選檔案格式的軟體,格式選【ANSI】



(完)

相關

[研究][BAT]顯示本機IPv4值

[研究][BAT]顯示本機IPv4值

2024-03-31

環境:Windows 10

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

NetworkIP.bat

FOR /F "tokens=2 delims=[]" %%a in ('ping -4 -n 1 %computername% ^| findstr [') do set NetworkIP=%%a
echo %NetworkIP%


NetworkIP2.bat (用 @ECHO OFF 關閉顯示執行的每道命令)

@ECHO OFF
FOR /F "tokens=2 delims=[]" %%a in ('ping -4 -n 1 %computername% ^| findstr [') do set NetworkIP=%%a
echo %NetworkIP%

show_ipv4.bat

@rem show_ipv4.bat @echo off for /f "tokens=2 delims=:" %%i in ('ipconfig ^| findstr IPv4') do ( echo IPv4: %%i ) pause 

(完)

相關

2024年3月30日 星期六

[研究]ASP.NET, WebForm, 比較 DotNetZip 和 System.IO.Compression 差異 ?

[研究]ASP.NET, WebForm, 比較 DotNetZip 和 System.IO.Compression 差異 ?

2024-03-30

ASP.NET, WebForm, 請比較 DotNetZip 和 System.IO.Compression 差異 ? 優點 ? 缺點 ? 用比較表

ChatGPT 
以下是 DotNetZip 和 System.IO.Compression 的比較表格,包括它們的差異、優點和缺點:

特徵DotNetZipSystem.IO.Compression
來源第三方庫.NET Framework 4.5開始內建
功能提供豐富功能,如密碼保護、多卷壓縮等僅提供基本的壓縮和解壓縮功能
API 使用提供簡單易用的 API,並有較多壓縮和解壓縮選項API 較為基本,功能較少
依賴性需要單獨下載和集成,增加項目依賴性.NET 標準庫的一部分,無需額外下載
適用範圍適用於複雜的壓縮需求,具有更多功能和選項適用於簡單的壓縮需求,功能較基本
靈活性提供較多的功能和選項,更靈活易用功能較少,API 較為基本
優點- 提供豐富功能和選項 - 易用的 API - 靈活性高- 內建於 .NET Framework - 較輕量級
缺點- 需要單獨下載和集成 - 增加項目依賴性- 功能較少,不支援高級功能 - API 較基本

這個表格可以幫助你更清楚地理解 DotNetZip 和 System.IO.Compression 之間的差異、優點和缺點,以便根據項目的需求做出更好的選擇。


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


https://github.com/haf/DotNetZip.Semverd

This repository has been archived by the owner on May 15, 2024. It is now read-only.

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.

(完)

[研究]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,使用 ClosedXML 0.102.2 匯出、寫入 .xlsx(暫存、不暫存檔)

[研究]ASP.NET,WebForm,使用 ClosedXML 0.102.2 匯出、寫入 .xlsx(暫存、不暫存檔)

2024-03-29

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

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

延續下面,但改用 DataTable,而非把資料逐一放入 ws.Cell 儲存格中

[研究][ASP.NET]使用 ClosedXML 0.95.4 讀取匯入 .xlsx 到資料庫(暫存、不暫存檔)
http://shaurong.blogspot.com/2021/02/aspnet-closedxml-0954-xlsx.html

********************************************************************************
Default2.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">
        <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_Xlsx_By_ClosedXML" runat="server" Text="匯出(.xlsx)"
            OnClick="Button_Export_Xlsx_By_ClosedXML_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]=@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 ClosedXML.Excel;
using DocumentFormat.OpenXml.Spreadsheet;
using System;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.IO;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Configuration;

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

        }

        protected void Button_Export_Xlsx_By_ClosedXML_Click(object sender, EventArgs e)
        {
            string mainFileName = "匯出檔案名稱";
            string fd = (string)ConfigurationManager.AppSettings["TempFolder"] + @"\";
            if (!System.IO.Directory.Exists(fd))
            {
                System.IO.Directory.CreateDirectory(fd);
            }
            string dateTimeString = DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss-fff");
            // 若檔案名稱有中文字或特殊符號,Response.AddHeader() 輸出檔案名稱要編碼
            string outFileName = HttpUtility.UrlEncode(
                mainFileName, System.Text.Encoding.UTF8) + "-" +
                dateTimeString + ".xlsx";

            // XLWorkbook.SaveAs() 輸出檔案名稱不要用 HttpUtility.UrlEncode 編碼
            // Response.TransmitFile() 輸出檔案名稱不要用 HttpUtility.UrlEncode 編碼
            string dirFileName = fd + mainFileName + "-" +
                dateTimeString + ".xlsx";
            try
            {
                Response.Clear();
                Response.Buffer = true;
                Response.Charset = "";

                #region Export 

                // [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.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 = "";

                    var wb = new XLWorkbook();
                    var ws = wb.Worksheets.Add("工作表1");

                    // 否則會出現類似 The range 工作表1!A1:U57 overlaps with the worksheet's autofilter. 錯誤訊息
                    ws.AutoFilter.IsEnabled = false;
                    // 定義欄位名稱列
                    string[] columnNameArray = { "SN", "Field1", "Field2" };
                    // Column number must be between 1 and 16384
                    for (int i = 0; i < columnNameArray.Count(); i++)
                    {
                        ws.Cell(1, i + 1).Value = columnNameArray[i];
                    }
                   
                    // 讀取資料,資料寫入「工作表1」
                    string queryString = @"
--DECLARE  @FieldText nvarchar(50)
--SET @FieldText=N'abc'

SELECT * FROM [MyTable]
";
                    DataTable dataTable = new DataTable();
                    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();

                        SqlDataAdapter adapter = new SqlDataAdapter(command);
                        adapter.Fill(dataTable);

                        //var ws = wb.Worksheets.Add(dataTable, WorksheetName);
                        ws.Cell(2, 1).InsertData(dataTable.AsEnumerable());

                        //SqlDataReader reader = command.ExecuteReader();
                        //int rowIndex = 1;   // 1 是標題列
                        //while (reader.Read())
                        //{
                        //    rowIndex++;
                        //    for (int i = 0; i < reader.FieldCount; i++)
                        //    {
                        //        //reader[i]的 i 要從 0 開始
                        //        dataText = reader[i].ToString();

                        //        // 規則運算式語言 - 快速參考 | Microsoft Docs
                        //        // https://docs.microsoft.com/zh-tw/dotnet/standard/base-types/regular-expression-language-quick-reference

                        //        // 換掉特殊字元 (自己評估)
                        //        dataText = dataText.Replace("\r", "").Replace("\n", "").Replace("\t", "").Replace(",", ",").Replace("'", "′").Replace(@"""", "”");
                        //        dataText = dataText.Replace("\a", "").Replace("\b", "").Replace("\t", "").Replace("\v", "").Replace("\f", "").Replace("\\", "");

                        //        // Column number must be between 1 and 16384
                        //        ws.Cell(rowIndex, i + 1).Value = dataText;
                        //    }
                        //}

                        //設定區域範圍的  儲存格框線
                        //ws.Ranges("A1:F5").Style.Border.TopBorder = XLBorderStyleValues.Thin;
                        //string endCell = "S" + rowIndex.ToString();
                        string endCell = "C" + (dataTable.Columns.Count+1);
                        ws.Ranges("A1:" + endCell).Style.Border.TopBorder = XLBorderStyleValues.Thin;
                        ws.Ranges("A1:" + endCell).Style.Border.LeftBorder = XLBorderStyleValues.Thin;
                        ws.Ranges("A1:" + endCell).Style.Border.RightBorder = XLBorderStyleValues.Thin;
                        ws.Ranges("A1:" + endCell).Style.Border.BottomBorder = XLBorderStyleValues.Thin;

                        ws.Columns().AdjustToContents();// 自適應欄寬,這要在資料寫完後,檔案儲存關閉前再做

                        ws.Ranges("A1:" + endCell).Style.Alignment.Vertical = XLAlignmentVerticalValues.Top; // 水平向上對齊

                        Response.Clear();
                        Response.Buffer = true;
                        Response.ContentEncoding = Encoding.GetEncoding(950);   //950就是所謂的BIG5
                                                                                //Response.AddHeader("Content-Disposition", "attachment;filename=\"" +
                                                                                //    HttpUtility.UrlEncode(fileName, System.Text.Encoding.UTF8) + "-" +
                                                                                //    DateTime.Now.ToString("yyyyMMddHHmmss") + ".xlsx");
                        Response.AddHeader("Content-Disposition", "attachment;filename=\"" + outFileName);
                        //'Excel 2003 : "application/vnd.ms-excel"
                        //'Excel 2007 : "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"

                        //Extension       MIME Type
                        //.xlsx               application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
                        //.xltx                application/vnd.openxmlformats-officedocument.spreadsheetml.template
                        //.potx               application/vnd.openxmlformats-officedocument.presentationml.template
                        //.ppsx              application/vnd.openxmlformats-officedocument.presentationml.slideshow
                        //.pptx               application/vnd.openxmlformats-officedocument.presentationml.presentation
                        //.sldx               application/vnd.openxmlformats-officedocument.presentationml.slide
                        //.docx              application/vnd.openxmlformats-officedocument.wordprocessingml.document
                        //.dotx               application/vnd.openxmlformats-officedocument.wordprocessingml.template
                        //.xlam              application/vnd.ms-excel.addin.macroEnabled.12
                        //.xlsb               application/vnd.ms-excel.sheet.binary.macroEnabled.12

                        //Response.ContentType = "application/ms-excel";
                        Response.ContentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";

                        //Response.TransmitFile(@"C:\Program Files (x86)\IIS Express\Export.xlsx");
                        //dirFileName = dirFileName.Replace('\\', '/');   //轉換 Windows, Linux 不同路徑斜線
                        //dirFileName = dirFileName.Replace("/", "\\");  // 轉換斜線 / 成 \  ,因 \ 是特殊符號,要以 \\ 表示

                        // 方法1: 直接輸出
                        wb.SaveAs(myMemoryStream);
                        Response.BinaryWrite(myMemoryStream.ToArray());
                        // myMemoryStream.WriteTo(Response.OutputStream); //works too
                        Response.Flush();
                        Response.Close();

                        // 方法2: 若需要寫入檔案再輸出
                        wb.SaveAs(dirFileName);                 // 存檔,Debug 或其他用途
                                                                ////Response.WriteFile(savePath);
                                                                //Response.TransmitFile(dirFileName);   // 把存檔輸出

                        // 輸出結束
                        Response.End();

                        Label_MSG1.ForeColor = System.Drawing.Color.Green;
                        Label_MSG1.Text = "匯出成功。";
                        // 上面 Response 輸出檔案,所以下面 JavaScript alert 是不會跳出的
                        //Page.ClientScript.RegisterStartupScript(Page.GetType(), "message", "<script language='javascript' defer>alert('匯出成功。');</script>");
                    }
                }
                #endregion Export ODS
            }
            catch (Exception ex)
            {
                Label_MSG1.ForeColor = System.Drawing.Color.Red;
                string exMsg = "不明錯誤。";
                if (ex != null)
                {
                    exMsg = ex.ToString();
                }
                Label_MSG1.Text = exMsg;
                Page.ClientScript.RegisterStartupScript(Page.GetType(), "message", "<script language='javascript' defer>alert('匯出失敗。');</script>");
                // Exception Message 內容可能導致 JavaScript alert 無法顯示,所以下面這行可能無法跳出對話盒視窗。
                Page.ClientScript.RegisterStartupScript(Page.GetType(), "message", "<script language='javascript' defer>alert('" + exMsg + "');</script>");
            }
        }
        // ----------
    }
}

測試成功



(完)

相關

[研究]ASP.NET,WebForm,使用 ClosedXML 0.102.2 匯出、寫入 .xlsx(暫存、不暫存檔)
https://shaurong.blogspot.com/2024/03/aspnetwebform-closedxml-01022-xlsx.html

[研究][ASP.NET]ClosedXML元件常用屬性或方法http://shaurong.blogspot.com/2022/04/aspnetclosedxml.html

[研究][ASP.NET]使用 ClosedXML 0.95.4 讀取匯入 .xlsx 到資料庫(暫存、不暫存檔)
http://shaurong.blogspot.com/2021/02/aspnet-closedxml-0954-xlsx.html

[研究][ASP.NET]使用 ClosedXML 0.95.4 匯出、寫入 .xlsx(暫存、不暫存檔)
http://shaurong.blogspot.com/2021/02/aspnet-closedxml-0954-xlsx_17.html



[研究]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

[研究]Windows 10, 11, 2019, 2022 的 Windows Defender 內含那些 EDR 軟體或功能?

[研究]Windows 10, Windows 11, Windows Server 2019, Windows Server 2022 的 Windows Defender 內含那些 EDR 軟體或功能?

2024-03-29

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

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

User

甚麼是 EDR 軟體 ? 包含哪些功能 ?
ChatGPT
EDR 軟體代表「Endpoint Detection and Response」,翻譯為「端點偵測與回應」。它是一種用於保護企業網絡的安全軟體,專注於監控和保護端點設備(例如電腦、手機、平板等)免受各種威脅和攻擊的工具。

EDR 軟體通常具有以下功能:
  • 威脅偵測: 監控端點設備,以識別任何可能的安全威脅,包括惡意軟體、未授權的存取和其他異常活動。
  • 事件記錄: 記錄端點上的所有活動,以便在發生安全事件時進行調查和追蹤。
  • 威脅情報整合: 整合來自不同威脅情報來源的資訊,以及最新的威脅情報,以提高對新型攻擊的偵測能力。
  • 行為分析: 監控端點的活動模式,以檢測可能的異常行為,例如未經授權的檔案操作或系統訪問。
  • 自動化回應: 根據事前定義的規則或指示,對潛在的安全威脅進行自動化反應,例如隔離受感染的端點或阻止惡意流量。
  • 調查和回溯: 提供對安全事件的詳細調查功能,包括威脅起源和擴散路徑的追蹤。
  • 報告和分析: 生成關於安全事件、威脅趨勢和端點安全狀態的報告,以便進行風險評估和改進安全策略。
總的來說,EDR 軟體提供了一個全面的端點安全解決方案,幫助組織在面對不斷演變的安全威脅時保持敏感並迅速做出反應。

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

Windows 10, Windows 11, Windows Server 2019, Windows Server 2022 的 Windows Defender 內含那些 EDR 軟體或功能? 用比較表

ChatGPT

以下是 Windows 10、Windows 11、Windows Server 2019 和 Windows Server 2022 中 Windows Defender 提供的一些端點偵測與回應 (EDR) 相關功能或軟體的比較表:

功能/軟體Windows 10 Windows DefenderWindows 11 Windows DefenderWindows Server 2019 Windows DefenderWindows Server 2022 Windows Defender
惡意軟體偵測與防護
行為分析
即時保護
雲端安全資訊分享
安全中心
威脅情報整合
自動化回應
調查與報告

儘管這些作業系統中的 Windows Defender 提供了一些基本的端點安全功能,但若要獲得更高級的端點偵測與回應 (EDR) 功能,組織通常需要考慮訂閱 Microsoft Defender for Endpoint 或使用第三方的 EDR 解決方案。

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

Windows Server 2019畫面


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

Windows Defender 何時開始提供 ?

ChatGPT

Windows Defender 是微軟於2006年推出的反惡意軟體程式。它最初是一個獨立的反惡意軟體工具,用於掃描和移除電腦中的惡意軟體。後來,微軟將其整合到Windows作業系統中,成為Windows Vista及以後版本的內建安全解決方案。因此,Windows Defender 已經存在多年,並且是 Windows 作業系統的一部分。

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

Windows Defender 前身 ?

ChatGPT

Windows Defender 的前身是 Windows AntiSpyware,最初於2005年推出。Windows AntiSpyware 是一個獨立的反間諜軟體程式,用於檢測和移除電腦中的間諜軟體和廣告軟體。微軟在2006年收購了該軟體的開發商Giant Company Software,並將其整合到自己的產品線中,並於同年將其重新命名為Windows Defender。自那時起,Windows Defender已成為Windows作業系統的一個核心安全功能,用於檢測和防止惡意軟體的攻擊。

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

Microsoft 防毒軟體 歷史 ?

ChatGPT

Microsoft的防毒軟體歷史可以追溯到1990年代初期。以下是Microsoft防毒軟體的一些主要里程碑:

  • MS-DOS時代:在早期,Microsoft推出了一系列防毒軟體,以應對MS-DOS時代的電腦病毒。其中一個著名的產品是Microsoft Anti-Virus (MSAV)。
  • Windows 95及以後版本:隨著Windows 95和後續版本的推出,Microsoft開始將防毒軟體整合到Windows操作系統中。這包括提供基本的防病毒功能和安全更新。
  • Windows Defender前身:在Windows XP時代,Microsoft推出了Windows AntiSpyware,這是用於對抗間諜軟體和廣告軟體的工具。後來,這個產品在Windows Vista時被重新命名為Windows Defender。
  • Windows Defender的整合:自Windows Vista以後,Windows Defender被整合到Windows操作系統中,成為預設的反惡意軟體工具。隨著版本的更新,Windows Defender提供了更強大的防護功能,包括防病毒、防間諜軟體和其他惡意軟體的保護。
  • Windows Defender演進:隨著時間的推移,Windows Defender不斷演進和改進。微軟持續投入研發資源,使其成為一個功能強大且有效的安全解決方案,提供實時保護、自動掃描、防火牆集成等功能。

總的來說,Microsoft防毒軟體經歷了多個階段和演變,從早期的獨立產品到後來的整合到Windows操作系統中的核心安全功能。

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

Microsoft Security Essentials ?

ChatGPT

Microsoft Security Essentials(MSE)是微軟於2009年9月推出的免費防毒軟體。它提供了基本的防病毒和防間諜軟體功能,並可以安裝在Windows XP、Windows Vista和Windows 7等作業系統上。Microsoft Security Essentials的目標是為沒有內建防毒軟體的Windows版本提供基本的安全保護。然而,自Windows 8發佈後,微軟決定將Windows Defender整合到操作系統中,因此Windows 8及以後的版本已經包含了內建的防毒軟體,無需再安裝Microsoft Security Essentials。微軟建議Windows 8及以後版本的用戶使用內建的Windows Defender進行防毒保護。

2009 年 Windows 哪一版問世 ?

ChatGPT

2009年,Windows 7問世。Windows 7是微軟在2009年10月22日正式發佈的作業系統。它是Windows Vista的後繼版本,引入了許多改進和新功能,包括更快的啟動速度、改進的任務欄、支援觸控設備的增強功能、新的安全性功能等。Windows 7在推出後受到了廣泛的好評,成為了一個非常受歡迎的Windows版本,被許多用戶廣泛採用。

(完)

相關

[研究]ASP.NET,WebForm,要傳遞 SqlDataSource1.SelectParameters 當時的值

[研究]ASP.NET,WebForm,要傳遞 SqlDataSource1.SelectParameters 當時的值

2024-03-29

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

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

這是傳遞 DefaultValue

Dictionary<string, string> parameters = new Dictionary<string, string>();
foreach (Parameter parameter in SqlDataSource1.SelectParameters)
{
    parameters.Add(parameter.Name, parameter.DefaultValue);
}


下面是傳遞當時的值

Default.aspx

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

<!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:DropDownList ID="DropDownList1" runat="server">
            <asp:ListItem>A2</asp:ListItem>
        </asp:DropDownList>
        <asp:SqlDataSource ID="SqlDataSource1" runat="server" 
            ConnectionString="<%$ ConnectionStrings:MyDBConnectionString %>" 
            SelectCommand="SELECT * FROM [MyTable] WHERE Field2=@Field2">
            <SelectParameters>
                <asp:ControlParameter ControlID="DropDownList1" Name="Field2" PropertyName="SelectedValue" />
            </SelectParameters>
        </asp:SqlDataSource>
        <br />
        <asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Button" />
    </form>
</body>
</html>


Default.aspx.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Profile;
using System.Web.UI;
using System.Web.UI.WebControls;

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

        protected void Button1_Click(object sender, EventArgs e)
        {
            Dictionary<string, string> parameters = new Dictionary<string, string>();
            foreach (Parameter parameter in SqlDataSource1.SelectParameters)
            {
                string value = "";

                if (parameter is ControlParameter)
                {
                    ControlParameter controlParam = (ControlParameter)parameter;
                    if (controlParam.ControlID != "")
                    {
                        Control control = Page.FindControl(controlParam.ControlID);
                        if (control != null && control is TextBox)
                        {
                            value = (control as TextBox).Text;
                        }
                        if (control != null && control is DropDownList)
                        {
                            value = (control as DropDownList).Text;
                        }
                    }
                }
                else if (parameter is FormParameter)
                {
                    FormParameter formParam = (FormParameter)parameter;
                    value = HttpContext.Current.Request.Form[formParam.FormField];
                }
                else if (parameter is QueryStringParameter)
                {
                    QueryStringParameter queryParam = (QueryStringParameter)parameter;
                    value = HttpContext.Current.Request.QueryString[queryParam.QueryStringField];
                }
                else if (parameter is SessionParameter)
                {
                    SessionParameter sessionParam = (SessionParameter)parameter;
                    value = HttpContext.Current.Session[sessionParam.SessionField]?.ToString();
                }
                else if (parameter is CookieParameter)
                {
                    CookieParameter cookieParam = (CookieParameter)parameter;
                    value = HttpContext.Current.Request.Cookies[cookieParam.CookieName]?.Value;
                }
                else if (parameter is ProfileParameter)
                {
                    ProfileParameter profileParam = (ProfileParameter)parameter;

                    //error CS1503: 引數 1: 無法從 'System.Web.HttpContext' 轉換成 'string'
                    //value = ProfileBase.Create(Context, true)[profileParam.PropertyName]?.ToString();

                    //error CS1503: 引數 1: 無法從 'System.Web.HttpContext' 轉換成 'string'
                    //value = ProfileBase.Create(HttpContext.Current, true)[profileParam.PropertyName]?.ToString();

                    //error CS1503: 引數 1: 無法從 'System.Web.HttpContext' 轉換成 'string'
                    //ProfileBase profile = ProfileBase.Create(HttpContext.Current);
                    //value = profile.GetPropertyValue(profileParam.PropertyName)?.ToString();

                    ProfileBase profile = HttpContext.Current.Profile;
                    value = profile.GetPropertyValue(profileParam.PropertyName)?.ToString();
                }
                else if (parameter is ControlParameter)
                {
                    ControlParameter controlParam = (ControlParameter)parameter;
                    value = (controlParam.ControlID != "") ? ((WebControl)Page.FindControl(controlParam.ControlID))?.Attributes[controlParam.PropertyName] : "";
                }
                else if (parameter is Parameter)
                {
                    value = parameter.DefaultValue;
                }

                parameters.Add(parameter.Name, value);
            }
        }
    }
}

實際測試成功。

(完)

相關

[研究]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