Cách đọc mã QR trong PDF bằng Java

Giới thiệu

Bạn đã bao giờ cần trích xuất thông tin mã vạch từ hàng trăm hóa đơn PDF, nhãn vận chuyển hoặc tài liệu tồn kho chưa? Việc quét thủ công qua các trang là tẻ nhạt và dễ gây lỗi. Dù bạn đang xây dựng hệ thống xử lý tài liệu tự động hay xác thực tính xác thực của sản phẩm, việc tìm kiếm mã vạch một cách hiệu quả trong PDF có thể là thách thức.

Trong hướng dẫn này, bạn sẽ học cách read QR code PDF tài liệu một cách hiệu quả bằng cách sử dụng GroupDocs.Signature API. API mạnh mẽ này biến những giờ làm việc thủ công thành chỉ vài dòng code. Bạn có thể quét toàn bộ tài liệu, xác định các loại mã vạch cụ thể (như QR code hoặc Code128), và tự động trích xuất dữ liệu của chúng.

Bạn sẽ học được:

  • Cài đặt GroupDocs.Signature cho Java trong vài phút
  • Tìm kiếm chữ ký mã vạch trong tài liệu PDF
  • Cấu hình tùy chọn tìm kiếm để có kết quả chính xác, nhắm mục tiêu
  • Xử lý các loại mã vạch khác nhau (QR code, EAN, Code128, v.v.)
  • Khắc phục các vấn đề thường gặp và tối ưu hiệu năng

Hãy cùng bắt đầu!

Câu trả lời nhanh

  • GroupDocs.Signature có thể đọc mã QR từ PDF không? Có, nó phát hiện QR, Data Matrix, PDF417 và nhiều mã vạch 1D.
  • Có cần giấy phép cho môi trường sản xuất không? Cần giấy phép thương mại; bản dùng thử miễn phí có sẵn để đánh giá.
  • Phiên bản Java nào được yêu cầu? Java 8+ (khuyến nghị Java 11+).
  • Làm sao giới hạn tìm kiếm chỉ ở các trang cụ thể? Sử dụng BarcodeSearchOptions.setAllPages(false) và đặt setPageNumber().
  • API có an toàn đa luồng cho xử lý batch không? Có, khi bạn tạo một thể hiện Signature riêng cho mỗi luồng.

Tại sao tìm kiếm mã vạch trong PDF?

Trước khi đi vào chi tiết kỹ thuật, đây là lý do tại sao việc này quan trọng trong các ứng dụng thực tế:

Các kịch bản kinh doanh phổ biến

  • Xử lý hóa đơn – Tự động trích xuất số đơn hàng hoặc mã theo dõi từ hóa đơn nhà cung cấp.
  • Quản lý tồn kho – Quét danh mục sản phẩm và trích xuất mã SKU để cập nhật cơ sở dữ liệu.
  • Vận chuyển & Logistics – Xác minh mã theo dõi gói hàng trong manifest vận chuyển.
  • Xác thực tài liệu – Kiểm tra các tài liệu đã ký bằng cách kiểm tra mã vạch bảo mật nhúng.
  • Hồ sơ y tế – Trích xuất ID bệnh nhân hoặc mã đơn thuốc từ tài liệu y khoa.

GroupDocs.Signature API thực hiện phần “nặng” — bạn không cần lo lắng về xử lý ảnh, thuật toán giải mã mã vạch, hay phức tạp khi render PDF. Tất cả đã được tích hợp sẵn.

Các yêu cầu trước

Trước khi bắt đầu tutorial này, hãy chắc chắn bạn đã chuẩn bị đầy đủ:

Thư viện và phụ thuộc cần thiết

Bạn cần đưa thư viện GroupDocs.Signature vào dự án Java. Dưới đây là cách thêm bằng Maven hoặc Gradle:

Maven:

<dependency>
    <groupId>com.groupdocs</groupId>
    <artifactId>groupdocs-signature</artifactId>
    <version>23.12</version>
</dependency>

Gradle:

implementation 'com.groupdocs:groupdocs-signature:23.12'

Lưu ý: Luôn kiểm tra phiên bản mới nhất tại GroupDocs.Signature for Java releases. Sử dụng phiên bản mới nhất giúp bạn nhận được các bản sửa lỗi và tính năng mới.

Cài đặt môi trường

  • JDK 8 trở lên – GroupDocs.Signature yêu cầu tối thiểu Java 8 (khuyến nghị Java 11+ để hiệu năng tốt hơn).
  • IDE – Bất kỳ trình soạn thảo nào cũng được, nhưng IntelliJ IDEA hoặc Eclipse sẽ giúp bạn dễ dàng hơn với tính năng autocomplete và debug.
  • Tài liệu PDF – Chuẩn bị một file PDF mẫu có chứa mã vạch (hóa đơn, nhãn vận chuyển hoặc danh mục sản phẩm đều phù hợp).

Kiến thức nền tảng

Bạn nên quen thuộc với:

  • Cú pháp Java cơ bản và các khái niệm hướng đối tượng
  • Xử lý ngoại lệ bằng khối try‑catch
  • Sử dụng thư viện bên ngoài trong IDE

Nếu bạn mới với các thư viện Java của bên thứ ba, đừng lo — chúng tôi sẽ hướng dẫn từng bước.

Cài đặt GroupDocs.Signature cho Java

Bắt đầu với GroupDocs.Signature chỉ mất vài phút. Đây là quy trình thiết lập đầy đủ:

Bước 1: Thêm phụ thuộc

Sử dụng Maven hoặc Gradle để đưa thư viện vào (xem code ở trên). Sau khi thêm phụ thuộc, làm mới dự án để tải các file JAR.

Bước 2: Nhận giấy phép

GroupDocs cung cấp nhiều tùy chọn cấp phép:

  • Dùng thử miễn phí – Thích hợp cho việc thử nghiệm. Tải về từ GroupDocs releases.
  • Giấy phép tạm thời – Nhận 30 ngày truy cập đầy đủ qua Temporary License Page.
  • Giấy phép thương mại – Dành cho môi trường sản xuất, mua tại GroupDocs Purchase.

Mẹo chuyên nghiệp: Bắt đầu với bản dùng thử để xây dựng proof‑of‑concept, sau đó nâng cấp nếu API đáp ứng nhu cầu.

Bước 3: Khởi tạo cơ bản

Dưới đây là cách tạo đối tượng Signature để làm việc với PDF:

import com.groupdocs.signature.Signature;

String filePath = "YOUR_DOCUMENT_DIRECTORY/sample_signed.pdf"; // Replace with your PDF path
Signature signature = new Signature(filePath);

Lớp Signature là điểm vào chính. Nó tải PDF vào bộ nhớ và cung cấp các phương thức để tìm kiếm, xác thực và trích xuất dữ liệu chữ ký (bao gồm cả mã vạch).

Quan trọng: Đảm bảo đường dẫn file đúng và PDF tồn tại. Sai lầm phổ biến của người mới? Dùng dấu gạch chéo ngược trên Windows mà không escape (C:\\Documents\\file.pdf thay vì C:\Documents\file.pdf).

Hướng dẫn triển khai

Bây giờ đến phần thú vị — viết code để tìm kiếm mã vạch trong PDF của bạn.

Tìm kiếm chữ ký mã vạch trong tài liệu

Phần này chỉ cho bạn cách quét PDF và xác định tất cả các chữ ký mã vạch. Chúng tôi sẽ chia thành các bước dễ hiểu, kèm giải thích cho mỗi phần.

Bước 1: Khởi tạo đối tượng Signature

Bắt đầu bằng việc tải tài liệu PDF:

import com.groupdocs.signature.Signature;

String filePath = "YOUR_DOCUMENT_DIRECTORY/sample_signed.pdf"; // Replace with actual file path
Signature signature = new Signature(filePath);

Điều gì đang diễn ra
Lớp Signature mở PDF và chuẩn bị cho quá trình xử lý. Hãy tưởng tượng như mở một file trong trình soạn thảo — bạn đang nạp tài liệu vào bộ nhớ để làm việc.

Lưu ý thực tế
Nếu bạn xử lý PDF tải lên từ người dùng, luôn xác thực đường dẫn file và kiểm tra file có tồn tại trước khi tạo đối tượng Signature. Điều này ngăn ngừa các lỗi khó hiểu sau này.

Bước 2: Tạo BarcodeSearchOptions

Cấu hình cách bạn muốn tìm kiếm mã vạch:

import com.groupdocs.signature.options.search.BarcodeSearchOptions;

// Configure options for searching barcodes
BarcodeSearchOptions options = new BarcodeSearchOptions();
options.setAllPages(true); // Search every page in the document

Các tùy chọn cấu hình chính

  • setAllPages(true): Quét tất cả các trang. Đặt false nếu bạn chỉ muốn kiểm tra các trang cụ thể (cấu hình bằng setPageNumber()).
  • Tại sao lại quan trọng: Nếu bạn xử lý hóa đơn mà mã vạch luôn nằm ở trang 1, việc tìm kiếm toàn bộ trang sẽ lãng phí tài nguyên. Đối với manifest vận chuyển nhiều trang, bạn sẽ cần setAllPages(true).

Mẹo chuyên nghiệp: Bạn cũng có thể lọc theo loại mã vạch (xem phần Các loại mã vạch được hỗ trợ bên dưới). Điều này tăng tốc tìm kiếm khi bạn biết chính xác định dạng cần tìm.

Bước 3: Thực thi tìm kiếm và xử lý kết quả

Bây giờ chạy tìm kiếm và xử lý các kết quả:

import com.groupdocs.signature.domain.signatures.BarcodeSignature;
import java.util.List;

try {
    // Execute the barcode search
    List<BarcodeSignature> signatures = signature.search(BarcodeSignature.class, options);
    
    // Check if any barcodes were found
    if (signatures.isEmpty()) {
        System.out.println("No barcode signatures found in the document.");
    } else {
        System.out.println("Found " + signatures.size() + " barcode signature(s):\n");
        
        // Loop through each barcode and display details
        for (BarcodeSignature barcodeSignature : signatures) {
            System.out.println("----------------------------------------");
            System.out.println("Barcode Type: " + barcodeSignature.getEncodeType().getTypeName());
            System.out.println("Barcode Text: " + barcodeSignature.getText());
            System.out.println("Page Number: " + barcodeSignature.getPageNumber());
            System.out.println("Position: X=" + barcodeSignature.getLeft() + 
                             ", Y=" + barcodeSignature.getTop());
            System.out.println("Size: Width=" + barcodeSignature.getWidth() + 
                             ", Height=" + barcodeSignature.getHeight());
            System.out.println("----------------------------------------\n");
        }
    }
} catch (Exception e) {
    System.err.println("Error searching for barcodes: " + e.getMessage());
    e.printStackTrace();
} finally {
    // Always dispose of the signature object to free resources
    if (signature != null) {
        signature.dispose();
    }
}

Giải thích đoạn code

  1. Thực thi tìm kiếmsignature.search() quét PDF và trả về danh sách các đối tượng BarcodeSignature.
  2. Kiểm tra rỗng – Xác nhận có thực sự tìm thấy mã vạch (ngăn tránh lỗi null‑pointer).
  3. Trích xuất dữ liệu – Với mỗi mã vạch, chúng ta lấy:
    • Type – Định dạng mã vạch (QR Code, Code128, EAN13, …)
    • Text – Dữ liệu đã giải mã (số đơn hàng, mã theo dõi, SKU, …)
    • Location – Số trang và tọa độ X/Y
    • Dimensions – Chiều rộng và chiều cao (hữu ích cho việc xác thực)
  4. Xử lý lỗi – Khối try‑catch ngăn chương trình bị crash nếu có lỗi (PDF hỏng, file không tồn tại, …).
  5. Giải phóng tài nguyên – Khối finally đảm bảo đối tượng Signature được đóng đúng cách, giải phóng bộ nhớ.

Ứng dụng thực tế
Giả sử bạn đang xử lý nhãn vận chuyển. Bạn sẽ lấy giá trị getText() (số theo dõi) và lưu vào cơ sở dữ liệu. Số trang cho biết nhãn nào tương ứng với lô hàng nào khi bạn xử lý tài liệu batch.

Lọc theo loại mã vạch

Bạn có thể tăng tốc tìm kiếm bằng cách chỉ định loại mã vạch cần tìm:

import com.groupdocs.signature.domain.barcodes.BarcodeTypes;

BarcodeSearchOptions options = new BarcodeSearchOptions();
options.setEncodeType(BarcodeTypes.QR); // Only search for QR codes
options.setAllPages(true);

Khi nào nên lọc
Nếu bạn biết hóa đơn chỉ chứa mã Code128, việc lọc theo loại sẽ giảm thời gian xử lý 30‑50 % trên các tài liệu lớn.

Các loại mã vạch được hỗ trợ

GroupDocs.Signature có thể phát hiện nhiều định dạng mã vạch khác nhau. Dưới đây là các loại bạn có thể tìm kiếm:

Mã vạch 1D (Linear)

  • Code128 – Thông dụng trong vận chuyển và đóng gói
  • Code39 – Dùng trong ngành ô tô và quốc phòng
  • EAN13/EAN8 – Mã vạch sản phẩm bán lẻ (bạn thấy chúng trên mọi sản phẩm)
  • UPC‑A/UPC‑E – Tiêu chuẩn bán lẻ Bắc Mỹ
  • Interleaved2of5 – Kho và phân phối

Mã vạch 2D (Matrix)

  • QR Code – Phổ biến nhất — dùng cho URL, mật khẩu Wi‑Fi, thông tin thanh toán
  • Data Matrix – Định dạng gọn cho các vật phẩm nhỏ (linh kiện điện tử)
  • PDF417 – Thẻ ID chính phủ, vé máy bay, giấy phép lái xe
  • Aztec Code – Vé giao thông

Lọc theo loại (ví dụ ở trên) giúp bạn tập trung vào định dạng cần thiết.

Các trường hợp sử dụng thực tế

Dưới đây là cách các nhà phát triển đang áp dụng tìm kiếm mã vạch trong môi trường sản xuất:

1. Xử lý hóa đơn tự động

Kịch bản – Bộ phận kế toán nhận hơn 500 hóa đơn nhà cung cấp mỗi ngày dưới dạng PDF.
Giải pháp – Quét mỗi PDF để tìm mã Code39 chứa số hóa đơn, tự động khớp với đơn đặt hàng trong hệ thống ERP. Điều này loại bỏ nhập liệu thủ công và giảm lỗi.

// Pseudo-code workflow
for (PDF invoice : invoiceBatch) {
    List<BarcodeSignature> barcodes = searchBarcodes(invoice);
    String invoiceNumber = barcodes.get(0).getText();
    updateERPSystem(invoiceNumber, invoice);
}

2. Cập nhật tồn kho kho hàng

Kịch bản – Kho nhận lô hàng kèm theo danh sách đóng gói PDF chứa SKU dưới dạng mã EAN13.
Giải pháp – Trích xuất tất cả mã vạch từ danh sách, cập nhật số lượng tồn kho tự động và đánh dấu các sai lệch để kiểm tra.

3. Xác thực tài liệu

Kịch bản – Các tài liệu pháp lý có QR code chứa chữ ký mật mã để xác thực.
Giải pháp – Tìm QR code trong hợp đồng đã ký, giải mã dữ liệu chữ ký và xác thực với cơ quan chứng thực đáng tin cậy. Điều này đảm bảo tài liệu không bị giả mạo.

4. Quản lý hồ sơ y tế

Kịch bản – Hồ sơ bệnh nhân trong bệnh viện chứa báo cáo xét nghiệm PDF với mã Code128 cho ID mẫu.
Giải pháp – Tự động trích xuất ID mẫu và liên kết kết quả xét nghiệm với hồ sơ bệnh nhân trong hệ thống HIS.

Các vấn đề thường gặp và cách khắc phục

Dưới đây là những vấn đề bạn có thể gặp và cách giải quyết:

Vấn đề 1: “Không tìm thấy mã vạch” (Mặc dù bạn biết chúng tồn tại)

Nguyên nhân có thể

  • Chất lượng ảnh mã vạch quá thấp (mờ, pixel thấp)
  • PDF dựa trên ảnh nhưng mã vạch quá nhỏ
  • Bạn đang tìm kiếm loại mã vạch sai

Giải pháp

  1. Kiểm tra độ phân giải ảnh – Mã vạch cần ít nhất 200 DPI để phát hiện đáng tin cậy. Nếu bạn đang quét tài liệu, sử dụng 300 DPI hoặc cao hơn.
  2. Bỏ lọc loại – Đầu tiên tìm kiếm tất cả các loại mã vạch (không đặt setEncodeType()), sau đó thu hẹp khi đã xác định được nội dung tài liệu.
  3. Xác minh chất lượng mã vạch – Mở PDF bằng Adobe Acrobat và phóng to. Nếu mã vạch nhìn mờ đối với bạn, API cũng sẽ gặp khó khăn.

Vấn đề 2: OutOfMemoryError với PDF lớn

Nguyên nhân – Tải PDF 500 trang có hình ảnh độ phân giải cao tiêu tốn nhiều bộ nhớ.

Giải pháp

  1. Xử lý trang theo lô – Thay vì setAllPages(true), xử lý 50 trang mỗi lần:
for (int startPage = 1; startPage <= totalPages; startPage += 50) {
    BarcodeSearchOptions options = new BarcodeSearchOptions();
    options.setPageNumber(startPage);
    options.setPagesSetup(new PagesSetup());
    options.getPagesSetup().setLastPage(Math.min(startPage + 49, totalPages));
    
    List<BarcodeSignature> batchResults = signature.search(BarcodeSignature.class, options);
    // Process results...
}
  1. Tăng kích thước heap JVM – Thêm -Xmx4g vào lệnh Java để cấp 4 GB bộ nhớ (tùy chỉnh theo nhu cầu).

Vấn đề 3: Hiệu năng chậm trên tài liệu đa trang

Nguyên nhân – Tìm kiếm trên tất cả các trang tuần tự mất thời gian, đặc biệt với các mã vạch phức tạp như PDF417.

Giải pháp

  1. Xử lý song song – Nếu mã vạch luôn nằm ở các trang cụ thể (ví dụ trang 1 của hóa đơn), chỉ tìm kiếm những trang đó.
  2. Lưu cache kết quả – Nếu bạn xử lý cùng một tài liệu nhiều lần, lưu trữ dữ liệu mã vạch để tránh quét lại.
  3. Sử dụng SSD – Tốc độ I/O quan trọng khi tải PDF lớn. SSD giảm thời gian tải 60‑70 % so với HDD.

Vấn đề 4: Kết quả dương tính giả (Nhận dạng các mẫu ngẫu nhiên là mã vạch)

Nguyên nhân – Bảng, lưới hoặc các đường kẻ có thể bị API nhận nhầm là mã vạch.

Giải pháp – Xác thực kết quả bằng cách kiểm tra độ dài và định dạng của văn bản đã giải mã:

for (BarcodeSignature barcode : signatures) {
    String text = barcode.getText();
    
    // Example: Invoice numbers are always 10 digits
    if (text.matches("\\d{10}")) {
        // Valid invoice number
        processBarcode(barcode);
    } else {
        System.out.println("Skipping invalid barcode: " + text);
    }
}

Mẹo tối ưu hiệu năng cho tài liệu lớn

Xử lý hàng ngàn PDF? Đây là cách tối ưu:

1. Chiến lược xử lý batch

Thay vì xử lý từng file một, dùng thread pool để xử lý đồng thời nhiều PDF:

ExecutorService executor = Executors.newFixedThreadPool(4); // 4 parallel threads

for (String pdfPath : pdfFiles) {
    executor.submit(() -> {
        try (Signature sig = new Signature(pdfPath)) {
            List<BarcodeSignature> results = sig.search(BarcodeSignature.class, options);
            // Process results...
        } catch (Exception e) {
            e.printStackTrace();
        }
    });
}

executor.shutdown();
executor.awaitTermination(1, TimeUnit.HOURS);

Tăng tốc – Xử lý 1 000 file giảm từ ~2 giờ xuống ~30 phút trên máy 4 lõi.

2. Giảm phạm vi tìm kiếm

Nếu logic kinh doanh cho phép, hạn chế khu vực tìm kiếm:

// Only search the top‑right corner where barcodes are typically placed
options.setRectangle(new Rectangle(400, 50, 150, 150)); // X, Y, Width, Height

Tăng tốc – Nhanh hơn 40‑60 % trên các tài liệu có vị trí mã vạch cố định.

3. Giám sát sử dụng bộ nhớ

Đối với batch dài, theo dõi heap và gợi ý GC khi cần:

Runtime runtime = Runtime.getRuntime();
long usedMemory = runtime.totalMemory() - runtime.freeMemory();

if (usedMemory > (runtime.maxMemory() * 0.8)) {
    System.gc(); // Suggest garbage collection
}

Các thực tiễn tốt nhất

Tuân thủ các hướng dẫn sau để có code sẵn sàng cho production:

1. Luôn giải phóng đối tượng Signature

Bao bọc code trong try‑with‑resources (Java 7+) để tự động đóng tài nguyên:

try (Signature signature = new Signature(filePath)) {
    // Your search code here...
} // Automatically disposed

2. Xác thực file đầu vào

Trước khi xử lý, kiểm tra file có tồn tại và là PDF hợp lệ:

File pdfFile = new File(filePath);
if (!pdfFile.exists() || !pdfFile.canRead()) {
    throw new FileNotFoundException("PDF not found or not readable: " + filePath);
}

// Optional: Verify it's actually a PDF (check magic bytes)

3. Ghi log kết quả phát hiện mã vạch

Để debug và audit, ghi lại những gì bạn tìm thấy:

Logger logger = Logger.getLogger(BarcodeSearcher.class.getName());

for (BarcodeSignature barcode : signatures) {
    logger.info(String.format("Detected %s barcode '%s' on page %d at (%.2f, %.2f)",
        barcode.getEncodeType().getTypeName(),
        barcode.getText(),
        barcode.getPageNumber(),
        barcode.getLeft(),
        barcode.getTop()));
}

4. Xử lý đa dạng định dạng mã vạch

Các ngành công nghiệp khác nhau dùng chuẩn khác nhau. Hãy viết code linh hoạt:

switch (barcode.getEncodeType().getTypeName()) {
    case "QR":
        // QR codes might contain URLs or JSON data
        processQRCode(barcode.getText());
        break;
    case "Code128":
        // Code128 typically contains alphanumeric order/tracking numbers
        processTrackingNumber(barcode.getText());
        break;
    default:
        logger.warning("Unexpected barcode type: " + barcode.getEncodeType());
}

5. Kiểm thử với tài liệu thực tế

Đừng chỉ dùng các PDF mẫu hoàn hảo. Hãy thử với tài liệu thực tế từ môi trường production:

  • Hóa đơn quét có vết cà phê
  • Nhãn vận chuyển fax có nhiễu
  • Ảnh chụp điện thoại độ phân giải thấp chuyển sang PDF

Điều này sẽ phát hiện các trường hợp góc cạnh mà demo không hiển thị.

Câu hỏi thường gặp

Q: Tôi có thể đọc QR code PDF mà không có giấy phép không?
A: Bản dùng thử miễn phí cho phép đọc QR code PDF để đánh giá, nhưng cần giấy phép thương mại cho triển khai production.

Q: API có hỗ trợ PDF được bảo mật bằng mật khẩu không?
A: Có. Bạn có thể truyền mật khẩu khi tạo đối tượng Signature: new Signature(filePath, "password").

Q: Làm sao cải thiện phát hiện trên bản quét độ phân giải thấp?
A: Tăng DPI của bản quét nguồn (tối thiểu 200 DPI) và cân nhắc lọc theo loại mã vạch để giảm dương tính giả.

Q: Tìm kiếm có an toàn đa luồng không?
A: Mỗi luồng nên sử dụng một thể hiện Signature riêng. API an toàn đa luồng khi dùng cách này.

Q: Phiên bản GroupDocs.Signature nào được kiểm thử với tutorial này?
A: Code đã được xác thực với GroupDocs.Signature 23.12.

Kết luận

Bạn vừa học cách read QR code PDF tài liệu bằng Java và GroupDocs.Signature API. Tóm tắt những gì đã đề cập:

Cài đặt – Thêm GroupDocs.Signature vào dự án và các tùy chọn cấp phép
Triển khai – Code hoàn chỉnh để tìm kiếm, trích xuất và xử lý dữ liệu mã vạch
Các loại mã vạch – Hiểu các định dạng được hỗ trợ (1D và 2D)
Ứng dụng thực tế – Xử lý hóa đơn, quản lý kho, xác thực tài liệu, hồ sơ y tế
Khắc phục – Giải quyết các vấn đề thường gặp như lỗi bộ nhớ và dương tính giả
Hiệu năng – Tối ưu tìm kiếm cho quy mô lớn

GroupDocs.Signature API xử lý phần phức tạp của việc parse PDF và nhận dạng mã vạch, cho phép bạn tập trung vào logic kinh doanh. Dù bạn đang tự động hoá xử lý hóa đơn, xác thực nhãn vận chuyển, hay trích xuất dữ liệu tồn kho, bạn đã có một giải pháp mạnh mẽ.


Cập nhật lần cuối: 2026-03-01
Kiểm thử với: GroupDocs.Signature 23.12
Tác giả: GroupDocs