วิธีใช้ GroupDocs: การเปรียบเทียบเอกสาร Java ด้วย Streams – คู่มือฉบับสมบูรณ์

คำนำ

เคยต้องเปรียบเทียบหลายเวอร์ชันของเอกสารด้วยตนเอง จ้องจอเพื่อหาความแตกต่างหรือไม่? หากคุณทำงานกับสัญญา เอกสารทางกฎหมาย หรือเนื้อหาใด ๆ ที่ผ่านการแก้ไขหลายครั้ง คุณคงรู้ว่ากระบวนการนี้น่าเบื่อ (และเสี่ยงต่อข้อผิดพลาด) เพียงใด

เมื่อคุณสงสัย วิธีใช้ GroupDocs สำหรับงานนี้ คำตอบง่าย ๆ คือ: GroupDocs.Comparison สำหรับ Java ช่วยให้คุณอัตโนมัติกระบวนการทั้งหมด โดยเปรียบเทียบหลายเอกสารพร้อมกันโดยใช้ streams ที่ประหยัดหน่วยความจำ นี่ไม่ใช่แค่การประหยัดเวลา—แต่ยังเป็นการขจัดข้อผิดพลาดของมนุษย์และขยายขีดความสามารถในการประมวลผลเอกสารของคุณ

ในคู่มือนี้ เราจะพาคุณผ่านทุกอย่างที่ต้องรู้เกี่ยวกับการนำการเปรียบเทียบเอกสารแบบหลาย‑stream ไปใช้ใน Java คุณจะได้เรียนรู้ว่าเมื่อใดควรใช้วิธีนี้ วิธีหลีกเลี่ยงข้อผิดพลาดทั่วไป และแนวปฏิบัติการเปรียบเทียบเอกสารที่จะทำให้การนำไปใช้ของคุณพร้อมสำหรับการผลิต

คำตอบสั้น ๆ

  • ประโยชน์หลักของการเปรียบเทียบแบบ stream คืออะไร? ลดการใช้หน่วยความจำโดยประมวลผลเอกสารโดยตรงจาก streams
  • ฉันสามารถเปรียบเทียบมากกว่าสองเอกสารพร้อมกันได้หรือไม่? ได้, GroupDocs ให้คุณเปรียบเทียบหลายเอกสารเป้าหมายในรอบเดียว
  • ต้องมีลิขสิทธิ์แบบชำระเงินสำหรับไฟล์ขนาดใหญ่หรือไม่? ทดลองใช้ฟรีสามารถทดสอบได้; ลิขสิทธิ์เต็มจะลบข้อจำกัดขนาดสำหรับการผลิต
  • แนะนำให้ใช้ Java เวอร์ชันใด? Java 11+ ให้ประสิทธิภาพและความเข้ากันได้ดีที่สุด
  • วิธีนี้เหมาะกับแอปพลิเคชันเว็บหรือไม่? แน่นอน—การประมวลผลแบบ stream เข้ากันได้ดีกับสถานการณ์อัปโหลด‑และ‑เปรียบเทียบ

“วิธีใช้ GroupDocs” สำหรับ Java Document Comparison Streams คืออะไร?

การใช้ GroupDocs.Comparison กับ streams ใน Java หมายความว่าคุณจะส่งข้อมูลเอกสารโดยตรงจากอ็อบเจ็กต์ InputStream แทนการโหลดไฟล์ทั้งหมดเข้าในหน่วยความจำ วิธีนี้เหมาะอย่างยิ่งกับไฟล์ขนาดใหญ่ งานแบบ batch หรือสภาพแวดล้อมใด ๆ ที่ต้องการการใช้ทรัพยากรอย่างมีประสิทธิภาพ

ทำไมต้องใช้การเปรียบเทียบเอกสารแบบ Stream?

  • ประหยัดหน่วยความจำ – ไฟล์ Word, PDF หรือ Excel ขนาดใหญ่สามารถประมวลผลได้โดยไม่ทำให้ heap เต็ม
  • ขยายขนาดได้ – เปรียบเทียบเอกสารหลายร้อยไฟล์ในงาน batch หรือบริการคลาวด์
  • ประสิทธิภาพ – เวลาเริ่มทำงานเร็วขึ้นเพราะไฟล์ไม่ต้องโหลดเต็มก่อนเปรียบเทียบ
  • ความยืดหยุ่น – ทำงานได้อย่างราบรื่นในแอปเดสก์ท็อป, micro‑services, และ pipeline CI/CD

เมื่อใดควรใช้การเปรียบเทียบเอกสารแบบ Stream

ก่อนจะลงมือเขียนโค้ด ให้เข้าใจว่าการเปรียบเทียบแบบ stream มีความเหมาะสมเมื่อใด:

เหมาะกับสถานการณ์ต่อไปนี้

  • การประมวลผลเอกสารขนาดใหญ่ – ไฟล์ 50 MB+ ที่เป็นภาระต่อ heap
  • งานแบบ Batch – เปรียบเทียบหลายสิบหรือหลายร้อยไฟล์โดยไม่ต้องโหลดทั้งหมดพร้อมกัน
  • แอปพลิเคชันเว็บ – ผู้ใช้อัปโหลดเอกสารเพื่อเปรียบเทียบ; streams ช่วยให้เซิร์ฟเวอร์ใช้หน่วยความจำน้อยลง
  • เวิร์กโฟลว์อัตโนมัติ – การรวมกับ DMS หรือ pipeline CI/CD ที่ต้องการ diff ที่เร็วและเชื่อถือได้

ควรหลีกเลี่ยงการใช้ Stream เมื่อ

  • ไฟล์เล็กมาก (น้อยกว่า 10 MB) และความเรียบง่ายสำคัญกว่าการเพิ่มประสิทธิภาพ
  • คุณต้องทำหลายรอบการอ่านเนื้อหาเดียวกัน (เช่น การสกัดข้อความก่อนเปรียบเทียบ)
  • สภาพแวดล้อมมีหน่วยความจำเพียงพอและความซับซ้อนเพิ่มขึ้นไม่คุ้มค่า

ข้อกำหนดเบื้องต้นและการตั้งค่า

สิ่งที่คุณต้องมี

  • Java Development Kit (JDK) – เวอร์ชัน 8 หรือสูงกว่า (แนะนำ Java 11+)
  • Maven – สำหรับจัดการ dependency (หรือ Gradle หากคุณชอบ)
  • ความรู้พื้นฐาน Java – try‑with‑resources, streams, การจัดการ exception
  • เอกสารตัวอย่าง – ไฟล์ Word, PDF หรือ Excel บางไฟล์สำหรับการทดสอบ

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

การนำ GroupDocs.Comparison เข้าโปรเจกต์ทำได้ง่ายด้วย Maven เพียงเพิ่มการกำหนดค่าใน pom.xml ของคุณ:

<repositories>
    <repository>
        <id>repository.groupdocs.com</id>
        <name>GroupDocs Repository</name>
        <url>https://releases.groupdocs.com/comparison/java/</url>
    </repository>
</repositories>

<dependencies>
    <dependency>
        <groupId>com.groupdocs</groupId>
        <artifactId>groupdocs-comparison</artifactId>
        <version>25.2</version>
    </dependency>
</dependencies>

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

คุณสามารถเริ่มต้นใช้ GroupDocs.Comparison ด้วย ลิขสิทธิ์ทดลองฟรี — เหมาะสำหรับการทดสอบและโครงการขนาดเล็ก สำหรับการใช้งานในผลิตภัณฑ์ ให้รับ ลิขสิทธิ์ชั่วคราว ระหว่างการพัฒนาหรือซื้อลิขสิทธิ์เต็ม รุ่นทดลองใช้ได้สำหรับการเรียนรู้ แต่ไฟล์ขนาดใหญ่อาจเจอข้อจำกัด

คู่มือการทำตามขั้นตอน

ทำความเข้าใจแนวคิด Stream

เมื่อใช้ streams สำหรับการเปรียบเทียบเอกสาร คุณกำลังบอก Java ว่า “อย่าโหลดไฟล์ทั้งหมดเข้า memory. อ่านเฉพาะที่ต้องการเมื่อจำเป็น” สิ่งนี้สำคัญมากสำหรับเอกสารขนาดใหญ่หรือสภาพแวดล้อมที่มีหน่วยความจำจำกัด

ขั้นตอนที่ 1: เริ่มต้น Comparer ด้วยเอกสารต้นทาง

นี่คือจุดเริ่มต้น—สร้างอ็อบเจ็กต์ Comparer ด้วย stream ของเอกสารต้นทาง:

import com.groupdocs.comparison.Comparer;
import java.io.FileInputStream;
import java.io.InputStream;

try (InputStream sourceStream = new FileInputStream("YOUR_DOCUMENT_DIRECTORY/SOURCE_WORD")) {
    try (Comparer comparer = new Comparer(sourceStream)) {
        // Your comparer is now ready to accept target documents
        // The try-with-resources ensures proper cleanup
    }
}

ทำไมรูปแบบนี้ถึงได้ผล

  • try‑with‑resources ปิด stream อัตโนมัติ ป้องกัน memory leak
  • ไม่ต้องโหลดเอกสารต้นทางทั้งหมดเข้าสู่ memory ล่วงหน้า
  • มีการจัดการ exception อยู่แล้ว — หากไฟล์ไม่พบหรือเสียหาย คุณจะได้รับแจ้งทันที

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

ต่อไปให้เพิ่มเอกสารเป้าหมายตามต้องการ:

try (InputStream target1Stream = new FileInputStream("YOUR_DOCUMENT_DIRECTORY/TARGET1_WORD"),
     InputStream target2Stream = new FileInputStream("YOUR_DOCUMENT_DIRECTORY/TARGET2_WORD"),
     InputStream target3Stream = new FileInputStream("YOUR_DOCUMENT_DIRECTORY/TARGET3_WORD")) {
    comparer.add(target1Stream, target2Stream, target3Stream);
}

เคล็ดลับ: คุณสามารถเพิ่มเอกสารเป้าหมายได้ตามที่หน่วยความจำของระบบคุณรับได้ โดยทั่วไปการเปรียบเทียบ 10–15 ไฟล์พร้อมกันทำงานได้ดีบนเครื่องสมัยใหม่ส่วนใหญ่

ขั้นตอนที่ 3: เรียกเปรียบเทียบและสร้างผลลัพธ์

สุดท้ายให้รันการเปรียบเทียบและบันทึกผลลัพธ์:

import java.io.FileOutputStream;
import java.io.OutputStream;
import java.nio.file.Path;

try (OutputStream resultStream = new FileOutputStream("YOUR_OUTPUT_DIRECTORY/CompareMultipleDocumentsResult")) {
    final Path resultPath = comparer.compare(resultStream);
    System.out.println("Comparison complete! Results saved to: " + resultPath);
}

สิ่งที่เกิดขึ้นที่นี่

  • compare() ประมวลผลเอกสารเป้าหมายทั้งหมดเทียบกับต้นทาง
  • ผลลัพธ์ถูกเขียนโดยตรงไปยัง output stream ทำให้การใช้หน่วยความจำน้อยลง
  • คุณจะได้รับอ็อบเจ็กต์ Path ที่ชี้ไปยังไฟล์ผลลัพธ์ที่สร้างขึ้น

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

รวมทุกขั้นตอนไว้ในคลาสพร้อมใช้งานสำหรับการผลิต:

import com.groupdocs.comparison.Comparer;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Path;

public class DocumentComparisonExample {
    
    public static void compareMultipleDocuments() {
        try (InputStream sourceStream = new FileInputStream("YOUR_DOCUMENT_DIRECTORY/SOURCE_WORD")) {
            try (Comparer comparer = new Comparer(sourceStream)) {
                
                // Add multiple target documents for comparison
                try (InputStream target1Stream = new FileInputStream("YOUR_DOCUMENT_DIRECTORY/TARGET1_WORD"),
                     InputStream target2Stream = new FileInputStream("YOUR_DOCUMENT_DIRECTORY/TARGET2_WORD"),
                     InputStream target3Stream = new FileInputStream("YOUR_DOCUMENT_DIRECTORY/TARGET3_WORD")) {
                    
                    comparer.add(target1Stream, target2Stream, target3Stream);
                }
                
                // Generate comparison results
                try (OutputStream resultStream = new FileOutputStream("YOUR_OUTPUT_DIRECTORY/CompareMultipleDocumentsResult")) {
                    final Path resultPath = comparer.compare(resultStream);
                    System.out.println("Documents compared successfully! Check: " + resultPath);
                }
            }
        } catch (Exception e) {
            System.err.println("Error during document comparison: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

เปรียบเทียบหลายเอกสาร Java – แนวปฏิบัติที่ดีที่สุด

เมื่อคุณ เปรียบเทียบหลายเอกสาร Java ควรปฏิบัติตามแนวทางต่อไปนี้:

  • ขนาด Batch: จำกัดแต่ละ batch ให้อยู่ในขนาดที่ JVM ของคุณจัดการได้สบาย (10‑15 ไฟล์เป็นกฎทั่วไป)
  • Buffer ของ Stream: ใช้ BufferedInputStream พร้อมบัฟเฟอร์ 8 KB–32 KB เพื่อเพิ่มประสิทธิภาพ I/O
  • การแยกข้อผิดพลาด: ห่อการเพิ่มเป้าหมายแต่ละไฟล์ด้วย try‑catch ของตัวเอง เพื่อให้ไฟล์เสียหายไฟล์เดียวไม่ทำให้ batch ทั้งหมดหยุดทำงาน
  • Logging: บันทึกเวลาเริ่มและสิ้นสุดของแต่ละคู่เอกสารเพื่อช่วยวิเคราะห์ประสิทธิภาพ

ปัญหาที่พบบ่อยและวิธีแก้

ปัญหา 1: OutOfMemoryError กับเอกสารขนาดใหญ่

อาการ: แอปพลิเคชันพังด้วยข้อผิดพลาด heap‑space

วิธีแก้: เพิ่มขนาด heap ของ JVM และพิจารณาประมวลผลเอกสารเป็น batch เล็กลง:

java -Xmx2g -XX:+UseG1GC YourApplication

ปัญหา 2: สิทธิ์การเข้าถึงไฟล์

อาการ: FileNotFoundException หรือข้อผิดพลาด access‑denied

วิธีแก้: ตรวจสอบสิทธิ์ไฟล์และให้แน่ใจว่าแอปของคุณสามารถอ่านโฟลเดอร์ต้นทางได้:

File sourceFile = new File("YOUR_DOCUMENT_DIRECTORY/SOURCE_WORD");
if (!sourceFile.canRead()) {
    throw new IllegalStateException("Cannot read source file: " + sourceFile.getAbsolutePath());
}

ปัญหา 3: เอกสารเสียหายหรือรูปแบบไม่รองรับ

อาการ: การเปรียบเทียบล้มเหลวด้วย exception ที่เกี่ยวกับรูปแบบ

วิธีแก้: ตรวจสอบรูปแบบเอกสารก่อนทำการประมวลผล:

// Always validate files before processing
private boolean isValidDocument(String filePath) {
    try {
        // Add format validation logic here
        return new File(filePath).length() > 0;
    } catch (Exception e) {
        return false;
    }
}

เคล็ดลับการเพิ่มประสิทธิภาพสำหรับการผลิต

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

เมื่อจัดการหลาย stream ให้ควบคุมการใช้หน่วยความจำให้แคบที่สุด:

  • ใช้ BufferedInputStream – ห่อ stream ของไฟล์เพื่อเพิ่ม throughput
  • กำหนดขนาด Buffer ที่เหมาะสม – 8 KB–16 KB ทำงานดีสำหรับไฟล์ใหญ่
  • ตรวจสอบหน่วยความจำ – เครื่องมือ profiling ช่วยระบุคอขวด
// More efficient file handling for large documents
try (BufferedInputStream sourceStream = new BufferedInputStream(
        new FileInputStream("source.docx"), 16384)) { // 16KB buffer
    // Your comparison logic here
}

การจัดการไฟล์อย่างเหมาะสม

// Example of using a larger buffer for very big files
try (BufferedInputStream sourceStream = new BufferedInputStream(
        new FileInputStream("large-document.docx"), 32768)) { // 32KB buffer
    // Process with increased buffer size
}

การประมวลผลแบบพร้อมกัน

สำหรับงาน batch ให้ใช้ utility ของ Java สำหรับ concurrency:

ExecutorService executor = Executors.newFixedThreadPool(4);
// Process multiple comparison tasks in parallel
// Ensure thread‑safety of shared resources

แนวปฏิบัติสำหรับการผลิต

1. การจัดการข้อผิดพลาดและ Logging อย่างแข็งแรง

ทำ logging อย่างครอบคลุมเพื่อให้สามารถติดตามปัญหาได้เร็ว:

import java.util.logging.Logger;
import java.util.logging.Level;

private static final Logger logger = Logger.getLogger(DocumentComparisonExample.class.getName());

public void safeDocumentComparison() {
    try {
        // Your comparison logic
        logger.info("Document comparison completed successfully");
    } catch (Exception e) {
        logger.log(Level.SEVERE, "Document comparison failed", e);
        // Optionally retry or alert administrators
    }
}

2. การจัดการการตั้งค่า

หลีกเลี่ยงการ hard‑code path; ใช้ environment variables หรือไฟล์ config:

String sourceDir = System.getProperty("document.source.dir", "default/path");
String outputDir = System.getProperty("document.output.dir", "default/output");

3. การตรวจสอบและทำความสะอาดข้อมูลเข้า

ตรวจสอบ path อินพุตทุกครั้งก่อนเปิด stream:

private void validateDocumentPath(String path) {
    if (path == null || path.trim().isEmpty()) {
        throw new IllegalArgumentException("Document path cannot be null or empty");
    }
    
    File file = new File(path);
    if (!file.exists() || !file.isFile()) {
        throw new IllegalArgumentException("Invalid document path: " + path);
    }
}

กรณีใช้งานจริง

การตรวจสอบเอกสารกฎหมาย

บริษัทกฎหมายเปรียบเทียบเวอร์ชันสัญญาจากคู่สัญญาต่าง ๆ ติดตามการเปลี่ยนแปลงระหว่างร่าง และตรวจสอบความสอดคล้องโดยเปรียบเทียบเอกสารสุดท้ายกับเทมเพลต

เอกสารซอฟต์แวร์

ทีมพัฒนาตรวจสอบ API docs ระหว่างเวอร์ชัน, รีวิวสเปคเทคนิคจากผู้ร่วมพัฒนาหลายคน, และรักษาความสอดคล้องของชุดเอกสาร

การปฏิบัติตามและการตรวจสอบ

องค์กรตรวจสอบเอกสารตามกฎระเบียบ, ติดตามการเปลี่ยนแปลงนโยบาย, และสร้าง audit trail สำหรับการแก้ไขเอกสาร

คู่มือแก้ไขปัญหา

ปัญหาด้านประสิทธิภาพ

  • ปัญหา: การเปรียบเทียบใช้เวลานาน
  • วิธีแก้:
    • แบ่งไฟล์ใหญ่ออกเป็นส่วนย่อย
    • เพิ่ม heap ของ JVM (-Xmx)
    • ตรวจสอบ I/O ของดิสก์ – SSD ช่วยเพิ่มความเร็ว

ปัญหาด้านหน่วยความจำ

  • ปัญหา: แอปพลิเคชันหมดหน่วยความจำ
  • วิธีแก้:
    • เพิ่มขนาด heap (-Xmx)
    • ประมวลผลเอกสารเป็น batch เล็กลง
    • ใช้ buffer ขนาดใหญ่สำหรับ streams

ปัญหาการเข้าถึงไฟล์

  • ปัญหา: ไม่สามารถอ่านไฟล์ต้นทางหรือเป้าหมายได้
  • วิธีแก้:
    • ตรวจสอบสิทธิ์ไฟล์
    • ตรวจสอบว่าไฟล์ไม่ได้ถูกล็อกโดยโปรเซสอื่น
    • ใช้ absolute path เพื่อหลีกเลี่ยงความสับสนของ relative‑path

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

Q: ฉันสามารถเปรียบเทียบเอกสารที่ไม่ใช่ Word ได้หรือไม่?
A: แน่นอน! GroupDocs.Comparison รองรับ PDF, Excel, PowerPoint, และไฟล์ข้อความธรรมดา วิธี stream ทำงานสม่ำเสมอในทุกฟอร์แมตที่สนับสนุน

Q: จำนวนเอกสารสูงสุดที่สามารถเปรียบเทียบพร้อมกันคือเท่าไหร่?
A: ไม่มีขีดจำกัดแน่นอน แต่ข้อจำกัดจริงคือหน่วยความจำ, CPU, และเวลาในการประมวลผล การเปรียบเทียบ 10‑15 เอกสารพร้อมกันเป็นปกติ; หากต้องการ batch ใหญ่กว่านั้นควรแบ่งเป็นชิ้นย่อย

Q: ฉันจะจัดการข้อผิดพลาดในการเปรียบเทียบอย่างไรให้ราบรื่น?
A: ใช้การจัดการ exception ชั้นหลายระดับ:

try {
    // Comparison logic
} catch (SecurityException e) {
    logger.warn("Access denied for file: " + fileName);
} catch (IOException e) {
    logger.error("I/O error during comparison", e);
} catch (Exception e) {
    logger.error("Unexpected error during comparison", e);
}

Q: สามารถปรับแต่งวิธีการไฮไลท์ความแตกต่างในผลลัพธ์ได้หรือไม่?
A: ได้. GroupDocs.Comparison มีตัวเลือกสไตล์สำหรับเนื้อหาที่แทรก, ลบ, หรือแก้ไข รวมถึงโทนสีและการใส่ metadata

Q: วิธีนี้เหมาะกับการเปรียบเทียบเอกสารแบบเรียลไทม์หรือไม่?
A: การเปรียบเทียบแบบ stream เหมาะกับสถานการณ์ที่ต้องการ latency ต่ำเพราะใช้หน่วยความจำน้อย สำหรับการแก้ไขร่วมแบบสดจริง ๆ ควรผสานกับ caching และเทคนิค diff แบบ incremental

Q: ควรจัดการกับเอกสารขนาดใหญ่มาก (100 MB+) อย่างไร?
A:

  1. เพิ่ม heap ของ JVM (-Xmx)
  2. ใช้ buffer ของ stream ขนาดใหญ่ (32 KB หรือมากกว่า)
  3. พิจารณาแบ่งเอกสารเป็นส่วนย่อย
  4. ติดตามการใช้หน่วยความจำด้วยเครื่องมือ profiling

สรุป

คุณได้มีพื้นฐานที่มั่นคงสำหรับการ วิธีใช้ GroupDocs ในการเปรียบเทียบเอกสาร Java ด้วย streams วิธีนี้ให้คุณจัดการไฟล์ขนาดใหญ่ได้อย่างมีประสิทธิภาพพร้อมโค้ดที่สะอาดและดูแลง่าย

ข้อสรุปสำคัญ

  • การเปรียบเทียบแบบ stream เหมาะกับการประมวลผลเอกสารขนาดใหญ่ที่ต้องการประหยัดหน่วยความจำ
  • ใช้ try‑with‑resources เพื่อทำความสะอาดอัตโนมัติ
  • ปรับใช้การจัดการข้อผิดพลาด, การตรวจสอบ, และ logging อย่างแข็งแรงสำหรับการผลิต
  • ปรับจูนประสิทธิภาพตามขนาดเอกสารและปริมาณงานของคุณ

ขั้นตอนต่อไป

  1. สำรวจการตั้งค่าขั้นสูง – สไตล์, metadata, ตัวเลือกรูปแบบผลลัพธ์
  2. รวมเข้ากับ Web Service – สร้าง endpoint REST ที่รับ stream ที่อัปโหลด
  3. อัตโนมัติกระบวนการ – ผสานกับ pipeline CI/CD เพื่อการตรวจสอบเอกสารต่อเนื่อง
  4. ทำ Profiling และ Optimisation – ใช้ Java Flight Recorder หรือ VisualVM เพื่อปรับจูนประสิทธิภาพ

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

แหล่งข้อมูลที่เกี่ยวข้อง:


อัปเดตล่าสุด: 2026-03-22
ทดสอบกับ: GroupDocs.Comparison 25.2
ผู้เขียน: GroupDocs