วิธีการรักษาเมตาดาต้าด้วย GroupDocs.Comparison ใน .NET

ในบทแนะนำนี้คุณจะได้เรียนรู้ วิธีการรักษาเมตาดาต้า เมื่อเปรียบเทียบเอกสารสองไฟล์ด้วย GroupDocs.Comparison สำหรับ .NET การรักษาเมตาดาต้าเป็นสิ่งสำคัญสำหรับการปฏิบัติตามกฎหมาย, ร่องรอยการตรวจสอบ, และกระบวนการทำงานร่วมกัน, และไลบรารีนี้ให้คุณควบคุมอย่างละเอียดว่าเมตาดาต้าของเอกสารใดจะคงอยู่ในผลลัพธ์การเปรียบเทียบ

บทนำ

เคยเปรียบเทียบเอกสารสองไฟล์แล้วทำให้เมตาดาต้าที่สำคัญหายไปหรือไม่? คุณไม่ได้เป็นคนเดียวที่เจอเรื่องนี้ เมื่อคุณต้อง รักษาเมตาดาต้าเป้าหมาย ขณะเปรียบเทียบเอกสารในแอปพลิเคชัน .NET งานนี้อาจดูซับซ้อน—แต่ไม่จำเป็นต้องเป็นเช่นนั้น

GroupDocs.Comparison สำหรับ .NET ให้คุณเลือกว่าเมตาดาต้าของเอกสารใดจะคงอยู่ในผลลัพธ์การเปรียบเทียบ ไม่ว่าคุณจะสร้างระบบจัดการเอกสาร, จัดการสัญญากฎหมาย, หรือจัดการเนื้อหาที่ทำงานร่วมกัน คุณก็ต้องการเมตาดาต้าจากแหล่งเอกสารที่ถูกต้องทุกครั้ง

คำตอบสั้น ๆ

  • “การรักษาเมตาดาต้าเป้าหมาย” หมายความว่าอย่างไร? จะคงเมตาดาต้า (ผู้เขียน, วันที่สร้าง, คุณสมบัติกำหนดเอง ฯลฯ) จากเอกสารที่คุณกำหนดเป็นเป้าหมายเมื่อสร้างผลลัพธ์การเปรียบเทียบ
  • ต้องใช้เวอร์ชัน GroupDocs.Comparison ใด? เวอร์ชัน 25.4.0 หรือใหม่กว่า
  • สามารถใช้กับ .NET Core ได้หรือไม่? ใช่ – .NET Core 2.0+ หรือ .NET Framework 4.6.1+
  • ต้องมีลิขสิทธิ์สำหรับการใช้งานจริงหรือไม่? จำเป็นต้องมีลิขสิทธิ์เชิงพาณิชย์สำหรับการใช้งานจริง; เวอร์ชันทดลองฟรีใช้ได้สำหรับการเรียนรู้
  • ฟีเจอร์นี้ทำงานกับ PDF และ DOCX หรือไม่? ใช่ – รูปแบบ Office และ PDF หลักทั้งหมดรองรับการรักษาเมตาดาต้า

ทำไมการรักษาเมตาดาต้าถึงสำคัญ

ก่อนจะลงมือเขียนโค้ด, มาพูดถึงเหตุผลที่การรักษาเมตาดาต้าเป้าหมายเป็นสิ่งสำคัญ เมตาดาต้าเอกสารไม่ได้เป็นแค่ “ของดีที่มี” — มันมักเป็นข้อกำหนดทางกฎหมายหรือธุรกิจที่สำคัญ:

  • เอกสารทางกฎหมาย – ต้องคงเครื่องหมายความเป็นส่วนตัวของทนายความ‑ลูกความ
  • ไฟล์องค์กร – ต้องคงแท็กการปฏิบัติตามและห่วงโซ่การอนุมัติ
  • งานวิจัยทางวิชาการ – การระบุผู้เขียนและประวัติการแก้ไขเป็นสิ่งจำเป็น
  • เอกสารเทคนิค – การควบคุมเวอร์ชันและสถานะการตรวจสอบมีความสำคัญ

หากจัดการไม่ถูกต้อง คุณอาจลบข้อมูลที่ใช้เดือน ๆ ในการสร้างออกไปโดยบังเอิญ นั่นคือจุดที่ตัวเลือก รักษาเมตาดาต้าเป้าหมาย มีประโยชน์

ข้อกำหนดเบื้องต้น

ไลบรารีและเวอร์ชันที่ต้องการ

  • GroupDocs.Comparison for .NET: เวอร์ชัน 25.4.0 หรือใหม่กว่า (เวอร์ชันก่อนหน้ามีตัวเลือกเมตาดาต้าจำกัด)
  • .NET Framework: 4.6.1 หรือสูงกว่า, หรือ .NET Core 2.0+

การตั้งค่าสภาพแวดล้อม

  • Visual Studio (หรือ IDE C# ใดก็ได้ที่คุณชอบ)
  • ความรู้พื้นฐาน C# (ไม่ต้องลึกซึ้งมาก)
  • ตัวอย่างเอกสารสองไฟล์สำหรับการทดสอบ (Word .docx ทำงานได้ดี)

ความรู้พื้นฐานที่ต้องมี

คุณไม่จำเป็นต้องเป็นผู้เชี่ยวชาญ GroupDocs, แต่ควรคุ้นเคยกับ:

  • คำสั่ง using ของ C# และการจัดการไฟล์
  • แนวคิดพื้นฐานการประมวลผลเอกสาร
  • เมตาดาต้าคืออะไร (ผู้เขียน, ชื่อเรื่อง, คุณสมบัติกำหนดเอง ฯลฯ)

พร้อมหรือยัง? ไปตั้งค่ากันเลย

การตั้งค่า GroupDocs.Comparison สำหรับ .NET

การติดตั้ง GroupDocs.Comparison ทำได้ง่าย แต่มีข้อควรระวังบางอย่าง

ตัวเลือกการติดตั้ง

NuGet Package Manager Console (วิธีง่ายที่สุด):

Install-Package GroupDocs.Comparison -Version 25.4.0

.NET CLI (หากคุณชอบใช้บรรทัดคำสั่ง):

dotnet add package GroupDocs.Comparison --version 25.4.0

เคล็ดลับ: ระบุเวอร์ชันเสมอเพื่อหลีกเลี่ยงการเปลี่ยนแปลงที่ทำให้โครงการของคุณพังโดยไม่คาดคิด

การจัดหาลิขสิทธิ์

นี่คือจุดที่หลายคนติดขัดในขั้นแรก GroupDocs.Comparison ไม่ฟรี, แต่คุณมีตัวเลือก:

  • ทดลองใช้ฟรี – ฟังก์ชันเต็มสำหรับ 30 วัน, เหมาะสำหรับการประเมิน
  • ลิขสิทธิ์ชั่วคราว – ขยายระยะเวลาการทดลองหากต้องการเวลาเพิ่ม
  • ลิขสิทธิ์เชิงพาณิชย์ – สำหรับการใช้งานจริง (มีระดับราคาให้เลือกหลายระดับ)

ไม่ต้องกังวลเรื่องลิขสิทธิ์ตอนนี้หากคุณเพียงแค่เรียนรู้—เวอร์ชันทดลองรวมฟีเจอร์ รักษาเมตาดาต้าเป้าหมาย ทั้งหมดไว้แล้ว

การตรวจสอบการตั้งค่าเบื้องต้น

มาทดสอบให้แน่ใจว่าทุกอย่างทำงานด้วยการทดสอบง่าย ๆ:

using System.IO;
using GroupDocs.Comparison;

string sourceFilePath = "source.docx";
string targetFilePath = "target.docx";

// Initialize the Comparer object.
using (Comparer comparer = new Comparer(sourceFilePath))
{
    // Add the target document for comparison.
    comparer.Add(targetFilePath);
}

หากโค้ดคอมไพล์โดยไม่มีข้อผิดพลาด, คุณพร้อมแล้ว หากไม่สำเร็จ, ตรวจสอบการติดตั้งแพคเกจและคำสั่ง using อีกครั้ง

วิธีการรักษาเมตาดาต้าเป้าหมาย

โหลดไฟล์ต้นฉบับและไฟล์เป้าหมาย, จากนั้นบอก API ให้คงเมตาดาต้าของเป้าหมายในผลลัพธ์สุดท้าย

คำตอบโดยตรง (40‑70 คำ):
เพื่อรักษาเมตาดาต้าเป้าหมาย, สร้างอ็อบเจ็กต์ Comparer ด้วยเอกสารต้นฉบับ, เพิ่มเอกสารเป้าหมายผ่าน Add, ตั้งค่า CloneMetadataType = MetadataType.Target บน ComparisonOptions, แล้วเรียก Compare. วิธีนี้ทำให้ GroupDocs.Comparison คัดลอกผู้เขียน, วันที่สร้าง, คุณสมบัติกำหนดเอง, และเมตาดาต้าอื่น ๆ ทั้งหมดจากไฟล์เป้าหมายไปยังผลลัพธ์ที่สร้างขึ้น

ทำความเข้าใจการไหลของเมตาดาต้า

ในกระบวนการเปรียบเทียบทั่วไป:

  1. เอกสารต้นฉบับ ให้เนื้อหาพื้นฐาน
  2. เอกสารเป้าหมาย ให้การเปลี่ยนแปลงที่ต้องเปรียบเทียบกับต้นฉบับ
  3. เอกสารผลลัพธ์ รวมทั้งสองไฟล์, แต่เมตาดาต้าใครจะชนะ?

โดยค่าเริ่มต้น GroupDocs.Comparison ใช้เมตาดาต้าของเอกสารต้นฉบับ เพื่อ รักษาเมตาดาต้าเป้าหมาย คุณต้องบอก API อย่างชัดเจน

ขั้นตอนการทำงานแบบทีละขั้น

ขั้นตอนที่ 1: เริ่มต้นอ็อบเจ็กต์ comparer ของคุณ

Comparer เป็นคลาสหลักที่ประสานกระบวนการเปรียบเทียบ มันโหลดไฟล์ต้นฉบับ, ติดตามการเปลี่ยนแปลง, และสร้างผลลัพธ์

using (Comparer comparer = new Comparer(sourceFilePath))
{
    // All comparison operations happen within this scope
}

ทำไมต้องใช้คำสั่ง using? คำสั่งเหล่านี้ทำให้ทรัพยากรถูกปล่อยโดยอัตโนมัติ, ป้องกันการรั่วไหลของหน่วยความจำเมื่อประมวลผลเอกสารขนาดใหญ่ คุณจะขอบคุณตัวเองเมื่อต้องจัดการไฟล์ Word ขนาด 50 MB

ขั้นตอนที่ 2: เพิ่มเอกสารเป้าหมาย

Comparer.Add ลงทะเบียนไฟล์ที่มีการแก้ไขที่คุณต้องการเปรียบเทียบกับต้นฉบับ

comparer.Add(targetFilePath);

ข้อผิดพลาดทั่วไป: สับสนระหว่างต้นฉบับและเป้าหมาย คิดแบบนี้ — ต้นฉบับคือ “เวอร์ชันเดิม”, เป้าหมายคือ “เวอร์ชันอัปเดต”

ขั้นตอนที่ 3: ตั้งค่าชนิดเมตาดาต้า (จุดที่สำคัญ)

CloneMetadataType เป็นคุณสมบัติของ ComparisonOptions ที่กำหนดว่าเมตาดาต้าของเอกสารใดจะถูกคัดลอกเข้าสู่ผลลัพธ์

comparer.Compare(outputFileName, new SaveOptions() { CloneMetadataType = MetadataType.Target });

เกิดอะไรขึ้น? CloneMetadataType = MetadataType.Target บอก GroupDocs.Comparison ว่า “ฉันต้องการคงเมตาดาต้าของไฟล์เป้าหมายในผลลัพธ์สุดท้าย”

ตัวอย่างทำงานครบถ้วน

นี่คือโค้ดทั้งหมดรวมกันในโปรแกรมที่รันได้:

using System;
using System.IO;
using GroupDocs.Comparison;
using GroupDocs.Comparison.Options;

class Program
{
    static void Main(string[] args)
    {
        try
        {
            string sourceFile = "original_document.docx";
            string targetFile = "updated_document.docx";
            string outputFile = "comparison_result.docx";
            
            using (Comparer comparer = new Comparer(sourceFile))
            {
                comparer.Add(targetFile);
                
                // Preserve target document metadata
                comparer.Compare(outputFile, new SaveOptions() 
                { 
                    CloneMetadataType = MetadataType.Target 
                });
                
                Console.WriteLine($"Comparison completed! Check {outputFile}");
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine($"Error during comparison: {ex.Message}");
        }
    }
}

ข้อผิดพลาดที่ควรหลีกเลี่ยง

ปัญหาเส้นทางไฟล์ – ใช้เส้นทางเต็มหรือให้ไฟล์อยู่ในไดเรกทอรีทำงาน:

// Good
string sourceFile = Path.Combine(Directory.GetCurrentDirectory(), "docs", "source.docx");

// Risky (might work locally but fail in production)
string sourceFile = "source.docx";

การจัดการหน่วยความจำ – สำหรับเอกสารขนาดใหญ่, ควรห่ออ็อบเจ็กต์ Comparer ด้วยคำสั่ง using

ความเข้ากันได้ของเวอร์ชัน – เวอร์ชันต่าง ๆ ของ GroupDocs.Comparison มีตัวเลือกเมตาดาต้าที่แตกต่างกัน—ใช้เวอร์ชัน 25.4.0 หรือใหม่กว่าเพื่อผลลัพธ์ที่ดีที่สุด

สถานการณ์เมตาดาต้าขั้นสูง

เมื่อควรใช้เมตาดาต้าเป้าหมาย vs. เมตาดาต้าต้นฉบับ

สถานการณ์ควรใช้เมตาดาต้า เป้าหมายควรใช้เมตาดาต้า ต้นฉบับ
ต้องการข้อมูลผู้เขียนที่อัปเดต
เอกสารต้นฉบับมีอำนาจทางกฎหมาย
มีคุณสมบัติกำหนดเองเพิ่มในไฟล์ใหม่เท่านั้น
ต้องการเก็บประวัติ “เอกสารหลัก”

การจัดการหลายไฟล์เป้าหมาย

คุณสามารถเปรียบเทียบกับหลายเป้าหมายพร้อมยังคงรักษาเมตาดาต้าจากเป้าหมายแรกที่เพิ่มเข้ามา:

using (Comparer comparer = new Comparer(sourceFilePath))
{
    comparer.Add(targetFilePath1);
    comparer.Add(targetFilePath2);
    comparer.Add(targetFilePath3);
    
    // Metadata will come from the first target document
    comparer.Compare(outputFileName, new SaveOptions() 
    { 
        CloneMetadataType = MetadataType.Target 
    });
}

การประยุกต์ใช้จริงและกรณีศึกษา

การจัดการเอกสารทางกฎหมาย

บริษัทกฎหมายมักต้องเปรียบเทียบเวอร์ชันสัญญาโดยคงเครื่องหมายเมตาดาต้าเฉพาะ:

// Preserve client metadata from updated contract
using (Comparer comparer = new Comparer("original_contract.docx"))
{
    comparer.Add("client_revised_contract.docx");
    
    comparer.Compare("final_contract_comparison.docx", new SaveOptions() 
    { 
        CloneMetadataType = MetadataType.Target  // Keep client's metadata
    });
}

การทำงานร่วมกันในงานวิจัยและการศึกษา

เมื่อหลายนักวิจัยทำงานร่วมกัน, คุณต้องการคงข้อมูลผู้เขียนล่าสุด:

// Keep metadata from the researcher's latest submission
using (Comparer comparer = new Comparer("draft_paper.docx"))
{
    comparer.Add("researcher_updates.docx");
    
    comparer.Compare("paper_comparison.docx", new SaveOptions() 
    { 
        CloneMetadataType = MetadataType.Target  // Preserve researcher metadata
    });
}

กระบวนการปฏิบัติตามข้อกำหนดขององค์กร

ในอุตสาหกรรมที่มีการควบคุม, การรักษาเมตาดาต้าการปฏิบัติตามเป็นสิ่งสำคัญ:

// Preserve compliance tags from updated policy document
using (Comparer comparer = new Comparer("old_policy.docx"))
{
    comparer.Add("compliance_approved_policy.docx");
    
    comparer.Compare("policy_comparison.docx", new SaveOptions() 
    { 
        CloneMetadataType = MetadataType.Target  // Keep compliance metadata
    });
}

การแก้ไขปัญหาที่พบบ่อย

ข้อผิดพลาด “ไม่พบไฟล์”

เป็นปัญหาที่พบบ่อยที่สุด ตรวจสอบด้วยเงื่อนไขชัดเจน:

string sourceFile = "source.docx";

// Always check if files exist before comparison
if (!File.Exists(sourceFile))
{
    Console.WriteLine($"Source file not found: {Path.GetFullPath(sourceFile)}");
    return;
}

// Same for target files
if (!File.Exists(targetFile))
{
    Console.WriteLine($"Target file not found: {Path.GetFullPath(targetFile)}");
    return;
}

ปัญหาหน่วยความจำกับเอกสารขนาดใหญ่

สำหรับเอกสารที่มีขนาดเกิน 10 MB, พิจารณาการปรับแต่งต่อไปนี้:

// Use explicit disposal for large documents
using (var comparer = new Comparer(sourceFile))
{
    comparer.Add(targetFile);
    
    var saveOptions = new SaveOptions() 
    { 
        CloneMetadataType = MetadataType.Target 
    };
    
    comparer.Compare(outputFile, saveOptions);
    
    // Explicitly clean up
    GC.Collect();
    GC.WaitForPendingFinalizers();
}

ปัญหาการอนุญาตและการเข้าถึง

เมื่อทำงานกับไฟล์ที่มีการป้องกันหรือแชร์บนเครือข่าย:

try
{
    using (var comparer = new Comparer(sourceFile))
    {
        comparer.Add(targetFile);
        comparer.Compare(outputFile, new SaveOptions() 
        { 
            CloneMetadataType = MetadataType.Target 
        });
    }
}
catch (UnauthorizedAccessException ex)
{
    Console.WriteLine("Access denied. Check file permissions.");
    Console.WriteLine($"Details: {ex.Message}");
}
catch (IOException ex)
{
    Console.WriteLine("File I/O error occurred.");
    Console.WriteLine($"Details: {ex.Message}");
}

การพิจารณาประสิทธิภาพและแนวทางปฏิบัติที่ดีที่สุด

การจัดการหน่วยความจำ

GroupDocs.Comparison สามารถใช้หน่วยความจำสูงสุดถึง 300 MB เมื่อประมวลผล PDF 100 หน้า ใช้คำสั่ง using เพื่อรับประกันการปล่อยทรัพยากรและลดการใช้หน่วยความจำอย่างรวดเร็ว

// Good - automatic resource cleanup
using (var comparer = new Comparer(sourceFile))
{
    // comparison logic here
}

// Bad - potential memory leaks
var comparer = new Comparer(sourceFile);
// ... comparison logic
// comparer.Dispose(); // Easy to forget!

ประมวลผลเป็นชุด – หากต้องเปรียบเทียบหลายไฟล์, ให้จัดการเป็นกลุ่มย่อยเพื่อรักษาการใช้หน่วยความจำให้ต่ำ

การทำงานแบบ Async เพื่อความตอบสนองที่ดีขึ้น

สำหรับแอปเดสก์ท็อปหรือเว็บ, ห่อการเปรียบเทียบในเมธอด async:

public async Task<bool> CompareDocumentsAsync(string source, string target, string output)
{
    return await Task.Run(() =>
    {
        try
        {
            using (var comparer = new Comparer(source))
            {
                comparer.Add(target);
                comparer.Compare(output, new SaveOptions() 
                { 
                    CloneMetadataType = MetadataType.Target 
                });
                return true;
            }
        }
        catch
        {
            return false;
        }
    });
}

แนวทางขนาดไฟล์

  • ขนาดเล็ก (< 1 MB) – ประมวลผลโดยตรง
  • ขนาดกลาง (1‑10 MB) – แสดงความคืบหน้าเพื่อให้ UI ตอบสนองได้ดี
  • ขนาดใหญ่ (> 10 MB) – ใช้การประมวลผลแบบ async เสมอและพิจารณาเรียก GC อย่างชัดเจนตามตัวอย่างข้างบน

การบูรณาการกับระบบขนาดใหญ่

การบูรณาการกับ ASP.NET Core

ด้านล่างเป็นคอนโทรลเลอร์พร้อมใช้งานที่รับไฟล์อัปโหลดสองไฟล์, รันการเปรียบเทียบ, และคืนผลลัพธ์พร้อม รักษาเมตาดาต้าเป้าหมาย:

[ApiController]
[Route("api/[controller]")]
public class DocumentComparisonController : ControllerBase
{
    [HttpPost("compare-with-target-metadata")]
    public async Task<IActionResult> CompareWithTargetMetadata(
        IFormFile sourceFile, 
        IFormFile targetFile)
    {
        var tempSource = Path.GetTempFileName();
        var tempTarget = Path.GetTempFileName();
        var outputPath = Path.GetTempFileName();
        
        try
        {
            // Save uploaded files temporarily
            await sourceFile.CopyToAsync(new FileStream(tempSource, FileMode.Create));
            await targetFile.CopyToAsync(new FileStream(tempTarget, FileMode.Create));
            
            // Perform comparison with target metadata preservation
            using (var comparer = new Comparer(tempSource))
            {
                comparer.Add(tempTarget);
                comparer.Compare(outputPath, new SaveOptions() 
                { 
                    CloneMetadataType = MetadataType.Target 
                });
            }
            
            // Return comparison result
            var resultBytes = await System.IO.File.ReadAllBytesAsync(outputPath);
            return File(resultBytes, "application/vnd.openxmlformats-officedocument.wordprocessingml.document", 
                       "comparison_result.docx");
        }
        finally
        {
            // Clean up temporary files
            if (System.IO.File.Exists(tempSource)) System.IO.File.Delete(tempSource);
            if (System.IO.File.Exists(tempTarget)) System.IO.File.Delete(tempTarget);
            if (System.IO.File.Exists(outputPath)) System.IO.File.Delete(outputPath);
        }
    }
}

คำถามที่พบบ่อย

ถาม: สามารถรักษาเมตาดาต้าจากหลายไฟล์เป้าหมายได้หรือไม่เมื่อเปรียบเทียบ?
ตอบ: เมื่อคุณเพิ่มไฟล์เป้าหมายหลายไฟล์, GroupDocs.Comparison จะใช้เมตาดาต้าจาก ไฟล์เป้าหมายแรก ที่เพิ่มเข้ามา จัดลำดับไฟล์ตามที่คุณต้องการให้เมตาดาต้าถูกเก็บไว้

ถาม: ถ้าไฟล์เป้าหมายไม่มีฟิลด์เมตาดาต้าบางอย่างจะเกิดอะไรขึ้น?
ตอบ: เฉพาะเมตาดาต้าที่มีอยู่ในไฟล์เป้าหมายจะถูกคัดลอกไปยังผลลัพธ์ ฟิลด์ที่ขาดหายจะถูกละเว้น; การเปรียบเทียบยังคงสำเร็จ

ถาม: จะจัดการกับเอกสารที่มีรหัสผ่านอย่างไร?
ตอบ: LoadOptions กำหนดการตั้งค่าเช่นรหัสผ่านสำหรับเปิดไฟล์ที่ป้องกัน ใช้วัตถุ LoadOptions พร้อมรหัสผ่านแล้วส่งให้คอนสตรัคเตอร์ Comparer:

var loadOptions = new LoadOptions() { Password = "your_password" };
using (var comparer = new Comparer(sourceFile, loadOptions))
{
    // comparison logic here
}

ถาม: มีวิธีรักษาเฉพาะคุณสมบัติเช่นเมตาดาต้าบางส่วนหรือไม่?
ตอบ: API ปัจจุบันจะรักษา เมตาดาต้าทั้งหมด จากแหล่งที่เลือก (Target หรือ Source) หากต้องการควบคุมระดับละเอียด คุณต้องดึงคุณสมบัติมาเองหลังการเปรียบเทียบแล้วนำกลับไปใช้ใหม่

ถาม: ฟอร์แมตเอกสารใดบ้างที่รองรับการรักษาเมตาดาต้า?
ตอบ: รูปแบบธุรกิจที่นิยม—DOCX, PDF, PPTX, XLSX และอื่น ๆ อีกหลายรูปแบบ—รองรับการรักษาเมตาดาต้า ดูเอกสารอย่างเป็นทางการสำหรับรายการเต็ม

ถาม: จะขอความช่วยเหลือได้จากที่ไหนหากเจอปัญหา?
ตอบ: เยี่ยมชม ฟอรั่มสนับสนุน GroupDocs เพื่อรับความช่วยเหลือจากชุมชน, หรือ ติดต่อฝ่ายสนับสนุนของ GroupDocs โดยตรงหากคุณมีลิขสิทธิ์เชิงพาณิชย์

แหล่งข้อมูลเพิ่มเติม


อัปเดตล่าสุด: 2026-09-15
ทดสอบกับ: GroupDocs.Comparison 25.4.0 for .NET
ผู้เขียน: GroupDocs


บทแนะนำที่เกี่ยวข้อง