ไลบรารีการทำหมายเหตุ PDF สำหรับ Java: สร้างการตอบกลับหมายเหตุ java

หากคุณต้องการ create annotation reply java สำหรับ PDF—ไม่ว่าคุณจะกำลังสร้างพอร์ทัลการตรวจสอบสัญญา ระบบการเรียนรู้ออนไลน์ หรือกระบวนการประมวลผลแบบกลุ่ม—คู่มือนี้จะแสดงให้คุณเห็นอย่างชัดเจนว่าต้องทำอย่างไรด้วย GroupDocs.Annotation สำหรับ Java เราจะอธิบายขั้นตอนการตั้งค่า การสร้างหมายเหตุแบบ squiggly การจัดเธรดการตอบกลับ และการปรับประสิทธิภาพ เพื่อให้คุณสามารถส่งมอบโซลูชันที่เชื่อถือได้ในไม่กี่วัน ไม่ใช่หลายสัปดาห์

คำตอบด่วน

  • วัตถุประสงค์หลักของ GroupDocs.Annotation คืออะไร? มันช่วยให้สามารถสร้าง แก้ไข และดึงข้อมูลหมายเหตุ PDF อย่างโปรแกรมได้ใน Java.
  • ฉันจะเพิ่มหมายเหตุแบบ squiggly อย่างไร? สร้างอินสแตนซ์ของ SquigglyAnnotation ตั้งค่ารูปร่างและสไตล์ แล้วเรียก annotator.add(...).
  • ฉันสามารถแนบการตอบกลับไปยังหมายเหตุได้หรือไม่? ได้—สร้างอ็อบเจ็กต์ Reply ตั้งค่าผู้เขียนและข้อความ แล้วเชื่อมโยงกับหมายเหตุหลัก.
  • ฉันต้องการไลเซนส์สำหรับการใช้งานจริงหรือไม่? แน่นอน; หากไม่มีไลเซนส์ที่ถูกต้อง ผลลัพธ์จะมีลายน้ำ.
  • เหมาะสำหรับการประมวลผลแบบแบตช์หรือไม่? ได้—ใช้ try‑with‑resources เพื่อเปิดเอกสารแต่ละไฟล์ ทำหมายเหตุ แล้วปิด เพื่อรักษาการใช้หน่วยความจำให้ต่ำ.

ทำไมนักพัฒนา Java จึงต้องการไลบรารีการทำหมายเหตุ PDF

การทำหมายเหตุ PDF ด้วยตนเองใช้เวลานานและเสี่ยงต่อข้อผิดพลาด โดยเฉพาะเมื่อคุณต้องตรวจสอบสัญญาหรือกระดาษสอบหลายร้อยฉบับ ไลบรารีการทำหมายเหตุ PDF สำหรับ Java จะทำงานนี้โดยอัตโนมัติ ให้คุณฝังไฮไลท์, เส้นใต้แบบ squiggly, และคอมเมนต์แบบเธรดโดยตรงในไฟล์ ผลลัพธ์คือเอกสารที่ค้นหาได้, พกพาได้ และคงรักษาการทำหมายเหตุทั้งหมดโดยไม่ต้องใช้โปรแกรมดูแยก

สิ่งที่คุณจะเรียนรู้ในคู่มือนี้

  • การติดตั้งและการขอไลเซนส์ GroupDocs.Annotation ในโครงการ Maven
  • การสร้างหมายเหตุแบบ squiggly ที่ดูเหมือนเส้นใต้ของ Word ดั้งเดิม
  • การเพิ่มการตอบกลับแบบเธรดให้กับหมายเหตุใด ๆ เพื่อการตรวจสอบร่วมกัน
  • การปรับแต่งการใช้หน่วยความจำและ CPU เมื่อประมวลผล PDF ขนาดใหญ่
  • การปรับใช้โซลูชันใน Spring Boot, micro‑services หรือแอปเดสก์ท็อป

ไม่ว่าคุณจะกำลังสร้างระบบตรวจสอบเอกสารทางกฎหมาย, เครื่องมือให้คะแนนการศึกษา, หรือกระบวนการควบคุมคุณภาพอัตโนมัติ เทคนิคต่อไปนี้จะให้พื้นฐานที่พร้อมใช้งานในระดับผลิต

create annotation reply java คืออะไร?

create annotation reply java คือกระบวนการโปรแกรมเมติกของการแนบเธรดคอมเมนต์ (Reply) ไปยังหมายเหตุ PDF ที่มีอยู่โดยใช้ Java การตอบกลับทำให้ผู้ตรวจสอบหลายคนสามารถอภิปรายการทำหมายเหตุเฉพาะโดยไม่ต้องออกจากเอกสาร ส่งเสริมการทำงานร่วมกันแบบต่อเนื่องในที่เดียว ความสามารถนี้ทำให้ PDF ที่เป็นสแตติกกลายเป็นแพลตฟอร์มการสนทนาแบบโต้ตอบ โดยคงบริบทและบันทึกการตรวจสอบไว้ภายในไฟล์โดยตรง

ข้อกำหนดเบื้องต้น: เตรียมสภาพแวดล้อมของคุณ

ก่อนที่เราจะลงลึกในโค้ด ให้ตรวจสอบว่าเครื่องพัฒนาของคุณตรงตามสเปคเหล่านี้:

  • JDK 8 หรือสูงกว่า (แนะนำ JDK 11 + เพื่อประสิทธิภาพการเก็บขยะที่ดีกว่า)
  • Maven หรือ Gradle สำหรับการจัดการ dependencies (ตัวอย่างใช้ Maven)
  • IDE ที่รองรับ Maven (IntelliJ IDEA, Eclipse หรือ VS Code)
  • อย่างน้อย 2 GB ของ RAM ว่างสำหรับ IDE และการทดสอบ
  • ไฟล์ PDF ตัวอย่างสำหรับการทดลอง (คุณสามารถสร้าง PDF ง่าย ๆ ด้วยโปรแกรมแก้ไข PDF ใดก็ได้)

GroupDocs.Annotation ทำงานทั้งหมดในกระบวนการเดียว; ไม่ต้องการโปรแกรมดู PDF ภายนอกหรือไลบรารีเนทีฟ

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

การรวมไลบรารีเป็นกระบวนการหลายขั้นตอน แต่มีข้อผิดพลาดที่ซ่อนอยู่บางอย่างที่อาจทำให้เกิดข้อผิดพลาดขณะรันได้หากคุณพลาด

การกำหนดค่า Maven Dependency

เพิ่ม repository และ dependency ลงใน pom.xml ของคุณ วางองค์ประกอบ <repositories> ก่อน <dependencies> เพื่อให้ Maven สามารถ resolve artifact ได้

<repositories>
    <repository>
        <id>groupdocs-repo</id>
        <url>https://repo.groupdocs.com/repo</url>
    </repository>
</repositories>

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

เคล็ดลับ: ตรวจสอบหน้าการปล่อยของ GroupDocs เพื่อดูเวอร์ชันล่าสุด การปล่อยใหม่มักรวมการสนับสนุนมาตรฐาน PDF ที่กำลังเกิดขึ้นและการปรับปรุงประสิทธิภาพ

การตั้งค่าไลเซนส์ (ห้ามข้ามขั้นตอนนี้!)

GroupDocs.Annotation ต้องการไฟล์ไลเซนส์สำหรับการใช้งานในผลิตภัณฑ์ หากไม่มี ไฟล์ PDF ที่สร้างขึ้นทุกไฟล์จะมีลายน้ำ

  1. Free Trial – ชุดฟีเจอร์เต็มสำหรับ 30 วัน เหมาะสำหรับการประเมิน
  2. Temporary License – เหมาะสำหรับการพัฒนาและการทดสอบภายใน
  3. Full License – จำเป็นสำหรับการใช้งานเชิงพาณิชย์ใด ๆ

วางไฟล์ GroupDocs.Annotation.lic ไว้ในโฟลเดอร์ resources ของคุณและโหลดมันเมื่อเริ่มต้น:

License license = new License();
license.setLicense("GroupDocs.Annotation.lic");

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

คู่มือการทำงานเต็มรูปแบบ: การเพิ่มหมายเหตุแบบ Squiggly

ต่อไปนี้เป็นขั้นตอนแบบทีละขั้นตอนที่แสดงวิธี create annotation reply java ขณะสร้างหมายเหตุแบบ squiggly แต่ละขั้นตอนมีคำอธิบายสั้น ๆ เพื่อให้คุณเข้าใจ “ทำไม” ของแต่ละบรรทัด

ขั้นตอน 1: นำเข้าคลาสที่จำเป็นทั้งหมด

import com.groupdocs.annotation.Annotator;
import com.groupdocs.annotation.models.Point;
import com.groupdocs.annotation.models.annotation.SquigglyAnnotation;
import com.groupdocs.annotation.models.annotation.Reply;
import com.groupdocs.annotation.options.SaveOptions;
  • Annotator เป็นจุดเริ่มต้นสำหรับการดำเนินการระดับเอกสารทั้งหมด.
  • Point แสดงพิกัดบนหน้า (X และ Y วัดจากมุมบนซ้าย).
  • SquigglyAnnotation กำหนดเส้นใต้แบบคลื่นที่ใช้เน้นข้อผิดพลาด.
  • Reply เก็บคอมเมนต์แบบเธรดที่แนบกับหมายเหตุ.
  • SaveOptions ให้คุณควบคุมรูปแบบเอาต์พุตและการบีบอัด.

ขั้นตอน 2: สร้างและกำหนดค่าหมายเหตุแบบ Squiggly ของคุณ

SquigglyAnnotation squiggly = new SquigglyAnnotation();
squiggly.setPageNumber(1);
squiggly.setColor(0xFFFF0000); // ARGB red
squiggly.setOpacity(0.7);
squiggly.setPoints(Arrays.asList(
    new Point(100, 200),
    new Point(300, 200)
));

SquigglyAnnotation เป็นคลาสที่สร้างเส้นใต้แบบคลื่นเพื่อเน้นข้อผิดพลาดใน PDF.

  • ระบบพิกัด: จุดเริ่มจากมุมบนซ้าย จุดสองจุดข้างต้นวาดเส้นคลื่นแนวนอนจาก (100, 200) ถึง (300, 200).
  • ความทึบแสง 0.7 หมายความว่าหมายเหตุมีความทึบ 70 % ทำให้ข้อความพื้นหลังยังคงอ่านได้.

ขั้นตอน 3: เพิ่มการตอบกลับแบบโต้ตอบ (เป็นตัวเลือกแต่มีประสิทธิภาพ)

Reply reply1 = new Reply();
reply1.setComment("Please double‑check this clause.");
reply1.setAuthor("Alice");
reply1.setCreatedOn(new Date());

Reply reply2 = new Reply();
reply2.setComment("I think the wording is correct.");
reply2.setAuthor("Bob");
reply2.setCreatedOn(new Date());

squiggly.setReplies(Arrays.asList(reply1, reply2));

Reply เป็นคลาสที่แสดงเธรดคอมเมนต์ที่แนบกับหมายเหตุ.

  • การตอบกลับสร้าง การสนทนาแบบเธรด โดยตรงบนหมายเหตุ จำลองประสบการณ์ของผู้ตรวจ PDF สมัยใหม่.
  • แต่ละการตอบกลับเก็บข้อมูลผู้เขียนและเวลาประทับ ซึ่งคุณสามารถกรองหรือแสดงใน UI ได้ในภายหลัง.

ขั้นตอน 4: ใช้หมายเหตุและบันทึกเอกสาร

try (Annotator annotator = new Annotator("input.pdf")) {
    annotator.add(squiggly);
    SaveOptions options = new SaveOptions();
    options.setOutputPath("output.pdf");
    annotator.save(options);
}
  • โครงสร้าง try‑with‑resources ปิด Annotator โดยอัตโนมัติ ปล่อยไฟล์แฮนด์เลและบัฟเฟอร์เนทีฟ.
  • save เขียน PDF ที่แก้ไขแล้วไปยัง output.pdf.

หมายเหตุเรื่องหน่วยความจำ: Annotator โหลดเฉพาะหน้าที่คุณแก้ไขเท่านั้น สำหรับ PDF หลายร้อยหน้า วิธีนี้ทำให้การใช้ heap ต่ำกว่า 150 MB บนเซิร์ฟเวอร์ทั่วไป

ตัวเลือกการกำหนดค่าขั้นสูง

ปรับแต่งลักษณะการแสดงผลของหมายเหตุ

คุณสามารถปรับแต่งสไตล์ภาพให้ตรงกับแนวทางแบรนด์ของคุณ:

squiggly.setBorderWidth(2);
squiggly.setColor(0xFF00FF00); // ARGB green
squiggly.setOpacity(0.5);
  • ความกว้างของเส้นขอบ ควบคุมความหนาของเส้น (หน่วย points).
  • รูปแบบ ARGB รวมช่องอัลฟาเพื่อความโปร่งใส.

การวางตำแหน่งหมายเหตุอย่างแม่นยำ

การหาพิกัดที่ถูกต้องอาจทำได้ยากบน PDF ที่มีขนาดหน้าต่าง ๆ ทำตามขั้นตอนต่อไปนี้:

  1. เปิด PDF ในโปรแกรมดู (เช่น Adobe Acrobat) แล้วบันทึกค่ามาตราส่วนของพื้นที่เป้าหมาย.
  2. แปลงค่ามาตราส่วน เป็น points (1 point = 1/72 inch).
  3. ใช้ annotator.getPageInfo(pageIndex) เพื่อดึงความกว้างและความสูงของหน้า แล้วคำนวณตำแหน่งสัมพัทธ์.

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

ปัญหา: หมายเหตุไม่แสดง

สาเหตุที่เป็นไปได้มากที่สุด

  • จุดอยู่ไกลเกินขอบของหน้า
  • ไลเซนส์ไม่ได้โหลด (ลายน้ำซ่อนหมายเหตุ)
  • หมายเลขหน้าผิด (หน้าใน API เริ่มจากศูนย์)

รายการตรวจสอบการแก้ไข

- Verify page dimensions with annotator.getPageInfo(pageIndex)
- Ensure all Point X/Y values are within [0, pageWidth] and [0, pageHeight]
- Confirm license file path and that license.setLicense() returns true
- Check that squiggly.setPageNumber(pageIndex) uses zero‑based indexing

ปัญหา: ประสิทธิภาพต่ำกับไฟล์ขนาดใหญ่

การโหลด PDF 500 หน้าเข้าสู่หน่วยความจำอาจทำให้บริการของคุณหยุดทำงาน ลดปัญหานี้โดย:

  • ประมวลผลหนึ่งหน้าต่อครั้ง – เปิดเอกสาร ทำหมายเหตุที่หน้าเดียว บันทึก แล้วย้ายไปหน้าถัดไป.
  • Streaming – ใช้ API streaming ของ Annotator เพื่อหลีกเลี่ยงการบัฟเฟอร์เอกสารทั้งหมด.
  • Caching – เก็บ PDF ที่เข้าถึงบ่อยในแคชเร็ว (เช่น Redis) แล้วทำหมายเหตุบนสำเนาที่แคช

ปัญหา: ค่าสีไม่ทำงาน

GroupDocs คาดหวัง ARGB (Alpha, Red, Green, Blue) ไม่ใช่ RGB ธรรมดา ค่า ARGB 0xFFFF0000 หมายถึงสีแดงทึบเต็ม หากคุณใส่ 0xFF0000 ไลบรารีจะตีความผิด ทำให้หมายเหตุเป็นสีดำ.

int argbRed = 0xFFFF0000; // Alpha=255, Red=255, Green=0, Blue=0
squiggly.setColor(argbRed);

แนวทางปฏิบัติที่ดีที่สุดสำหรับประสิทธิภาพ

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

เมื่อทำหมายเหตุหลายสิบ PDF ในงานแบตช์ ให้ห่อแต่ละไฟล์ในบล็อก try‑with‑resources ของตนเอง:

for (String filePath : pdfList) {
    try (Annotator annotator = new Annotator(filePath)) {
        // add annotations
        annotator.save(new SaveOptions().setOutputPath(filePath.replace(".pdf", "_annotated.pdf")));
    }
}
  • รูปแบบนี้รับประกันว่าบัฟเฟอร์เนทีฟจะถูกปล่อยหลังจากแต่ละรอบ ทำให้ป้องกัน OutOfMemoryError ในกระบวนการที่ทำงานนาน

การเพิ่มประสิทธิภาพการประมวลผลแบบแบตช์

สำหรับสภาพแวดล้อมที่ต้องการ throughput สูง พิจารณา parallel streams ร่วมกับ bounded thread pool:

ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
pdfList.parallelStream().forEach(path -> executor.submit(() -> annotateDocument(path)));
executor.shutdown();
executor.awaitTermination(1, TimeUnit.HOURS);
  • Thread pool ที่จำกัด ป้องกันการระเบิดของเธรด ในขณะที่ parallel streams ทำให้คอร์ CPU ทำงานเต็มที่

พิจารณาขนาดไฟล์

PDF ขนาดใหญ่ (> 100 MB) สามารถทำให้ประสิทธิภาพลดลง ใช้กลยุทธ์ต่อไปนี้:

  • บีบอัดล่วงหน้า PDF ต้นฉบับด้วยเครื่องมือเช่น Ghostscript ก่อนทำหมายเหตุ.
  • ทำหมายเหตุเฉพาะหน้าที่ต้องการ – ข้ามหน้าที่ไม่ต้องการทำหมายเหตุ.
  • แยก เอกสารเป็นส่วนที่มีความหมาย (เช่น ตามบท) แล้วประมวลผลแต่ละส่วนแยกกัน.

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

ระบบตรวจสอบเอกสาร

บริษัทกฎหมายมักต้องทำเครื่องหมายข้อกำหนดที่มีปัญหา Squiggly annotations ร่วมกับการตอบกลับแบบเธรดทำให้หลายทนายสามารถอภิปรายย่อหน้าหนึ่งโดยไม่ต้องออกจาก PDF:

  • Lawyer A เพิ่มเส้นใต้สีแดงใต้ข้อกำหนดและเขียนว่า “ข้อความคลุมเครือ”.
  • Lawyer B ตอบว่า “เพิ่มคำนิยามสำหรับ ‘material breach’”.
  • การสนทนาทั้งหมดจะฝังอยู่ใน PDF, สามารถค้นหา, พกพา, และตรวจสอบได้.

การรวมกับระบบที่มีอยู่

GroupDocs.Annotation ทำงานร่วมกับเฟรมเวิร์ก Java ยอดนิยมได้อย่างราบรื่น:

  • Spring Boot – เปิดเผย REST endpoint /api/annotate ที่รับไฟล์ PDF แบบ multipart, เพิ่มหมายเหตุ, และสตรีมผลลัพธ์กลับไปยังไคลเอนต์.
  • JSF – ผูกการกระทำหมายเหตุกับคอมโพเนนต์ UI เพื่อทำหมายเหตุแบบเรียลไทม์ในเว็บวิว.
  • Microservices – footprint เล็กของไลบรารี (< 15 MB) ทำให้คุณสามารถคอนเทนเนอร์ด้วย Docker และสเกลแนวนอนได้.

การทำงานอัตโนมัติ

รวมหมายเหตุกับผลิตภัณฑ์ GroupDocs อื่น ๆ (เช่น GroupDocs.Signature) เพื่อสร้าง pipeline แบบ end‑to‑end:

1. Upload contract → 2. Auto‑apply squiggly for missing signatures → 3. Add reviewer replies → 4. Route to signing service.

เมื่อใดควรใช้ Squiggly Annotations เทียบกับทางเลือกอื่น

Use‑caseRecommended annotation
การทำเครื่องหมายข้อผิดพลาดด้านการสะกดหรือไวยากรณ์Squiggly – สัญญาณภาพที่คล้ายกับโปรเซสเซอร์คำ
การไฮไลท์ส่วนสำคัญโดยไม่บ่งบอกว่ามีข้อผิดพลาดHighlight – ชั้นใส
การให้ข้อเสนอแนะโดยละเอียดText หรือ Comment – กล่องโน้ตแบบอิสระ
การอนุมัติหรือปฏิเสธเอกสารStamp – ป้าย “Approved” หรือ “Rejected”

สรุป

ตอนนี้คุณมีสูตรครบถ้วนพร้อมใช้งานในระดับผลิตสำหรับ create annotation reply java ด้วย GroupDocs.Annotation ด้วยการเชี่ยวชาญ API, การจัดการไลเซนส์, และการใช้เคล็ดลับประสิทธิภาพข้างต้น คุณสามารถ:

  • ทำการทำเครื่องหมายข้อผิดพลาดอัตโนมัติใน PDF พัน ๆ ฉบับ
  • เปิดใช้งานการสนทนาแบบเธรดร่วมกันภายในไฟล์
  • รักษาการใช้หน่วยความจำให้ต่ำแม้เมื่อประมวลผลเอกสารขนาดใหญ่

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

  1. ทดลองกับประเภทหมายเหตุอื่น ๆ (highlight, stamp, text).
  2. สร้างบริการ REST ที่รับ PDF, ทำหมายเหตุ, และส่งผลลัพธ์กลับ.
  3. สำรวจ API การดึงข้อมูล (annotator.get()) เพื่อดึงคอมเมนต์ที่มีอยู่สำหรับการวิเคราะห์.

พลังของการทำหมายเหตุ PDF แบบโปรแกรมเมติกอยู่ที่ความสามารถในการแทนที่การทำหมายเหตุด้วยมือที่น่าเบื่อด้วยโค้ดที่ทำซ้ำได้และตรวจสอบได้ ไม่ว่าคุณจะสร้างผลิตภัณฑ์ legal‑tech ที่เฉพาะเจาะจงหรือเอนจินการทำงานเอกสารทั่วไป เทคนิคในคู่มือนี้ให้พื้นฐานที่มั่นคงเพื่อก้าวต่อไป

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

ถาม: สิ่งที่ทำให้ GroupDocs.Annotation ดีกว่าห้องสมุด PDF Java อื่น ๆ คืออะไร?
A: GroupDocs.Annotation มุ่งเน้นเฉพาะกระบวนการทำหมายเหตุ ให้มากกว่า 30 ประเภทของหมายเหตุ, การตอบกลับแบบเธรด, และการสนับสนุนเนทีฟสำหรับไฟล์กว่า 50 รูปแบบ พร้อมคง footprint หน่วยความจำต่ำกว่า 200 MB สำหรับ PDF 500 หน้า.

ถาม: ฉันสามารถใช้ไลบรารีนี้กับแอปพลิเคชัน Spring Boot ได้หรือไม่?
A: ได้แน่นอน. สร้าง @RestController ที่ฉีด Annotator service, ประมวลผลการอัปโหลด multipart, และสตรีม PDF ที่ทำหมายเหตุกลับไปยังไคลเอนต์. อย่าลืมตั้งค่า thread‑pool สำหรับคำขอพร้อมกัน.

ถาม: ฉันจะจัดการกับเอกสารที่มีขนาดหน้าต่าง ๆ อย่างไร?
A: สอบถามขนาดของแต่ละหน้าโดยใช้ annotator.getPageInfo(pageIndex) แล้วคำนวณพิกัดสัมพัทธ์ (เช่น เปอร์เซ็นต์) แทนการกำหนดค่าจุดแบบคงที่ วิธีนี้ทำให้หมายเหตุแสดงผลถูกต้องบนหน้า A4, Letter, และหน้าขนาดกำหนดเอง.

ถาม: มีวิธีดึงหมายเหตุที่มีอยู่จาก PDF หรือไม่?
A: มี. เรียก annotator.get() เพื่อรับคอลเลกชันของหมายเหตุทั้งหมด, จากนั้นวนเพื่ออ่านคุณสมบัติเช่น ผู้เขียน, คอมเมนต์, และรูปทรง. มีประโยชน์สำหรับการย้ายหรือการวิเคราะห์.

ถาม: วิธีที่ดีที่สุดสำหรับการจัดการสิทธิ์การทำหมายเหตุในระบบหลายผู้ใช้คืออะไร?
A: ดำเนินการตรวจสอบสิทธิ์ที่ระดับแอปพลิเคชัน, เก็บ user ID กับแต่ละ Reply, และบังคับกฎธุรกิจ (เช่น ผู้เขียนหรือผู้ดูแลระบบเท่านั้นที่สามารถแก้ไขหรือลบการตอบกลับ). API เองไม่ได้บังคับสิทธิ์ ทำให้คุณมีความยืดหยุ่นเต็มที่.

ถาม: ฉันจะเพิ่มประสิทธิภาพการใช้หน่วยความจำเมื่อประมวลผล PDF หลายร้อยไฟล์อย่างไร?
A: ใช้ try‑with‑resources สำหรับแต่ละเอกสาร, ประมวลผลหน้าแยกกัน, และพิจารณา thread pool ที่จำกัดเพื่อจำกัดการใช้หน่วยความจำพร้อมกัน. การตรวจสอบ heap ของ JVM ด้วยเครื่องมือเช่น VisualVM ช่วยปรับ -Xmx ให้เหมาะสม.

Last Updated: 2026-05-16
Tested With: GroupDocs.Annotation 25.2 for Java
Author: GroupDocs

Additional Resources

{< /blocks/products/pf/tutorial-page-section >} {< /blocks/products/pf/main-container >} {< /blocks/products/pf/main-wrap-class >} {< blocks/products/products-backtop-button >}

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

<dependencies>
   <dependency>
      <groupId>com.groupdocs</groupId>
      <artifactId>groupdocs-annotation</artifactId>
      <version>25.2</version>
   </dependency>
</dependencies>
import com.groupdocs.annotation.Annotator;

// Initialize your annotator - this is your entry point to all annotation features
try (Annotator annotator = new Annotator("path/to/your/document.pdf")) {
    // All your annotation magic happens here
    System.out.println("Annotator initialized successfully!");
}
import com.groupdocs.annotation.Annotator;
import com.groupdocs.annotation.models.Point;
import com.groupdocs.annotation.models.Reply;
import com.groupdocs.annotation.models.annotationmodels.SquigglyAnnotation;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
// Create a new SquigglyAnnotation instance
SquigglyAnnotation squigglyAnnotation = new SquigglyAnnotation();

// Set the creation date of the annotation
squigglyAnnotation.setCreatedOn(new Date());

// Define font and background colors using RGB values
squigglyAnnotation.setFontColor(65535); // Yellow color in ARGB format
squigglyAnnotation.setBackgroundColor(16761035); // Light blue color in ARGB format

// Set a message to display with the annotation
squigglyAnnotation.setMessage("This is squiggly annotation");

// Define opacity (range 0.0 - 1.0)
squigglyAnnotation.setOpacity(0.7);

// Specify the page number for the annotation (zero-based index)
squigglyAnnotation.setPageNumber(0);

// Set squiggly line color specific to Word and PDF documents
squigglyAnnotation.setSquigglyColor(1422623); // Color code for squiggly lines

// Define points marking the start and end of the annotation on the page
List<Point> points = new ArrayList<>();
points.add(new Point(80, 730));
points.add(new Point(240, 730));
points.add(new Point(80, 650));
points.add(new Point(240, 650));
squigglyAnnotation.setPoints(points);
// Create replies to the annotation (optional)
Reply reply1 = new Reply();
reply1.setComment("First comment");
reply1.setRepliedOn(new Date());

Reply reply2 = new Reply();
reply2.setComment("Second comment");
reply2.setRepliedOn(new Date());

List<Reply> replies = new ArrayList<>();
replies.add(reply1);
replies.add(reply2);

// Associate replies with the annotation
squigglyAnnotation.setReplies(replies);
try (Annotator annotator = new Annotator("YOUR_DOCUMENT_DIRECTORY/input.pdf")) {
    // Add the prepared squiggly annotation to the document
    annotator.add(squigglyAnnotation);
    
    // Save the annotated document
    annotator.save("YOUR_OUTPUT_DIRECTORY/result_squiggly_annotation.pdf");
}
// Custom color configurations
squigglyAnnotation.setFontColor(0xFF0000); // Red text
squigglyAnnotation.setBackgroundColor(0x00FF00); // Green background
squigglyAnnotation.setSquigglyColor(0x0000FF); // Blue squiggly line

// Transparency effects
squigglyAnnotation.setOpacity(0.3); // Very subtle
// or
squigglyAnnotation.setOpacity(0.9); // Almost opaque
// Verify your points are within page boundaries
System.out.println("Page dimensions: " + annotator.getPageInfo(0));

// Check if your points make sense
List<Point> points = squigglyAnnotation.getPoints();
for (Point point : points) {
    System.out.println("Point: (" + point.getX() + ", " + point.getY() + ")");
}
// Wrong: RGB format
int wrongColor = 0xFF0000; // This might not work as expected

// Right: ARGB format
int rightColor = 0xFFFF0000; // Full opacity red
// Good practice: Use try-with-resources
try (Annotator annotator = new Annotator(inputPath)) {
    // Process annotations
    annotator.add(annotation);
    annotator.save(outputPath);
} // Automatic cleanup happens here

// Avoid: Manual resource management
Annotator annotator = new Annotator(inputPath); // Resources might leak
public void processBatch(List<String> documentPaths) {
    for (String path : documentPaths) {
        try (Annotator annotator = new Annotator(path)) {
            // Process each document independently
            addAnnotations(annotator);
            annotator.save(getOutputPath(path));
        } catch (Exception e) {
            // Handle individual document failures without stopping the batch
            System.err.println("Failed to process: " + path + " - " + e.getMessage());
        }
    }
}
public class DocumentWorkflow {
    public void reviewDocument(String documentPath, ReviewLevel level) {
        try (Annotator annotator = new Annotator(documentPath)) {
            switch (level) {
                case GRAMMAR_CHECK:
                    addGrammarAnnotations(annotator);
                    break;
                case LEGAL_REVIEW:
                    addLegalAnnotations(annotator);
                    break;
                case FINAL_PROOF:
                    addProofreadingAnnotations(annotator);
                    break;
            }
            annotator.save(getReviewedPath(documentPath));
        }
    }
}