ทุก repository จะสะสมข้อมูลเชิงโครงสร้างที่ในที่สุดใครสักคนต้องการเป็นเอกสาร: การเปลี่ยนแปลงในรุ่นใหม่, ผู้ร่วมทำงานของปี, รายการ API, รายการความเสี่ยงที่เปิดอยู่ ข้อมูลเหล่านี้เป็น JSON อยู่แล้ว; ขั้นตอนที่ขาดคือไฟล์ PDF หรือ Word ที่จัดรูปแบบแล้วซึ่งลูกค้า, ผู้ตรวจสอบ หรือผู้จัดการจะเปิดดูจริง ๆ ด้วย GroupDocs.Assembly.Mcp ที่ทำงานแบบโลคัลข้าง Claude Code (claude mcp add กับ dnx GroupDocs.Assembly.Mcp --yes), ตัวแทนจะเติมเทมเพลต Word ที่เก็บไว้ใน repo จากไฟล์ JSON ใน repo, และเขียนเป็น PDF, โดยไม่มีใครต้องจัดรูปแบบตาราง:

สร้าง PDF ของบันทึกการปล่อยรุ่น 4.2.0 จาก data/release-4.2.0.json ด้วย templates/release-notes.docx, และใบรับรองการมีส่วนร่วมสำหรับผู้ร่วมทำงานทุกคนใน data/contributors-2026.json.

เวอร์ชันขั้นตอนต่อขั้นตอนพร้อมการตั้งค่าและการแก้ไขปัญหาอยู่ในเอกสาร: วิธีสร้าง PDF หรือรายงาน Word จากข้อมูล JSON ใน repository ด้วย Claude Code.

ทำไมไม่ให้ตัวแทนการเขียนโค้ดสร้างเอกสาร?

ตัวแทนการเขียนโค้ดทำได้ดีมากในการสร้างข้อมูล แต่ค่อนข้างแย่ในการสร้างเอกสาร ขอให้มันสร้าง “บันทึกการปล่อยรุ่นเป็น PDF” มันจะเขียนไฟล์ Markdown, จากนั้นสคริปต์ที่แปลงไฟล์, แล้วดีบักฟอนต์ของสคริปต์นั้น รุ่นต่อไปมันจะทำอีกครั้งโดยแตกต่างกันเล็กน้อย ผลลัพธ์จะดูเหมือนค่าตั้งต้นของไลบรารีการแปลง, ไม่เหมือนเอกสารที่บริษัทของคุณส่งออก

เทมเพลตทำให้รูปลักษณ์คงที่และอยู่ภายใต้การควบคุมเวอร์ชัน templates/release-notes.docx เป็นไฟล์ Word ปกติที่มีโลโก้, สไตล์หัวเรื่องและตาราง, พร้อมแท็ก <<…>> บางส่วน ผู้ที่เป็นเจ้าของการจัดรูปแบบจะแก้ไขใน Word; ตัวแทนจะไม่ยุ่งกับมัน JSON จะถูกสร้างโดยเครื่องมือการปล่อยของคุณ, หรือโดยตัวแทนจาก git log, และนั่นคือส่วนที่ตัวแทนการเขียนโค้ดทำได้ดี

มันยังทำให้การทำงานสามารถตรวจสอบได้ การ pull request ที่เปลี่ยน data/release-4.2.0.json แสดงอย่างชัดเจนว่าการเปลี่ยนแปลงใดบ้างที่จะปรากฏในบันทึกการปล่อยรุ่น, บรรทัดต่อบรรทัด, ใน diff ที่ผู้ตรวจสอบสามารถอ่านได้ในหนึ่งนาที การ pull request ที่เปลี่ยน PDF ที่สร้างขึ้นจะไม่แสดงอะไรเลย การแยกข้อมูลและการจัดรูปแบบเป็นไฟล์ที่แยกกัน, มีเวอร์ชัน, และถือว่าเอกสารเป็นสิ่งที่คุณเรนเดอร์จากไฟล์เหล่านั้น, เป็นแนวคิดเดียวกับการแยกซอร์สโค้ดและผลลัพธ์การสร้าง, และใช้ได้กับเอกสารด้วยเหตุผลเดียวกัน

โครงสร้างของ repository

repo/
  data/
    release-4.2.0.json       {"release":{...}, "changes":[...4 items]}
    contributors-2026.json   {"contributors":[...3 items]}
  templates/
    release-notes.docx       <<[release.Version]>>, <<foreach [c in
                             changes]>> table row, counts
    certificate.docx         <<[contributor.Name]>> ...
  out/                       GROUPDOCS_MCP_OUTPUT_PATH, in .gitignore
        |
        |  Claude Code -> GroupDocs.Assembly MCP server (local, stdio)
        v
  release-notes-4.2.0.pdf    pnair.pdf  tvarga.pdf  mrossi.pdf

การเรียกใช้

ก่อนอื่นตัวแทนจะตรวจสอบว่าเทมเพลตต้องการอะไร, เพื่อให้มันบอกคุณได้ว่า JSON ขาดอะไรบ้าง:

-> get_template_fields {"template":{"filePath":
     "repo/templates/release-notes.docx"}}
<- { "dataSourceNames": [ "release", "changes" ],
     "fields": [ "release.Product", "release.Version", "release.Date",
                 "changes[].Type", "changes[].Title",
                 "changes[].PullRequest", "changes[].Author" ] }

จากนั้นการเรียกหนึ่งครั้งจะเรนเดอร์มัน:

-> assemble_document {"template":{"filePath":
     "repo/templates/release-notes.docx"},
     "data":{"filePath":"repo/data/release-4.2.0.json"},
     "format":"pdf","outputName":"release-notes-4.2.0.pdf"}
<- Assembled 'release-notes.docx' with 'release-4.2.0.json' (JSON
   object) as PDF
   Saved to: .../release-notes-4.2.0.pdf

แถวตารางของเทมเพลตจะทำซ้ำหนึ่งครั้งต่อการเปลี่ยนแปลง, และบรรทัดสุดท้ายจะนับจำนวนการเปลี่ยนแปลงและผู้เขียนที่แตกต่างกันด้วย changes.Count() และ changes.Select(c => c.Author).Distinct().Count() ตัวเลขเหล่านี้มาจากข้อมูลในเวลาที่เรนเดอร์, ไม่ได้มาจากตัวแทน

ใบรับรองเป็นการกระจาย: PDF หนึ่งไฟล์ต่อแต่ละองค์ประกอบของอาร์เรย์ contributors, ตั้งชื่อโดยใช้ handle ของผู้ร่วมทำงาน:

-> assemble_per_record {"template":{"filePath":
     "repo/templates/certificate.docx"},
     "data":{"filePath":"repo/data/contributors-2026.json"},
     "recordsPath":"contributors","fileNameField":"Handle",
     "format":"pdf"}
<- Assembled 3 of 3 document(s) from 'certificate.docx' with
   'contributors-2026.json', one per record (each record as
   'contributor'), as PDF.
   Saved to:
   .../pnair.pdf
   .../tvarga.pdf
   .../mrossi.pdf

recordsPath บอกเซิร์ฟเวอร์ว่าตำแหน่งของอาร์เรย์อยู่ที่ไหนเมื่อไฟล์ JSON เป็นอ็อบเจ็กต์, ซึ่งเป็นรูปแบบทั่วไปของไฟล์ข้อมูลจริง

ทำให้เป็นนิสัย, ไม่ใช่แค่คำสั่ง

ตัวแทนจะปฏิบัติตามคำแนะนำของโครงการเกี่ยวกับเวลาที่จะใช้เครื่องมือ บางบรรทัดใน CLAUDE.md หรือ AGENTS.md ทำให้สิ่งนี้กลายเป็นแนวปฏิบัติ:

Documents for people (release notes, reports, certificates) are generated
with the groupdocs-assembly MCP server from templates/*.docx and data/*.json.
Call get_template_fields first; never edit a template. Generated files land
in out/, which is in .gitignore. Dates in JSON as yyyy-MM-ddTHH:mm:ss.

เก็บผลลัพธ์ให้อยู่นอก git โดยค่าเริ่มต้นเซิร์ฟเวอร์จะเขียนใกล้โฟลเดอร์จัดเก็บของมัน; ตั้งค่า GROUPDOCS_MCP_OUTPUT_PATH ในการลงทะเบียนเซิร์ฟเวอร์ให้ชี้ไปที่โฟลเดอร์ out/ ของ repo และเพิ่มโฟลเดอร์นั้นใน .gitignore JSON และเทมเพลตเป็นแหล่งข้อมูล; PDF เป็น artefact ของการสร้าง, สร้างใหม่ในไม่กี่วินาที, และการคอมมิตมันจะทำให้เกิด diff ที่ไม่มีใครสามารถตรวจสอบได้

ข้อจำกัดที่จริงจัง

  • โหมดประเมินผล: ทุก PDF จะเริ่มด้วย “Evaluation Only. Created with GroupDocs.Assembly 26.7…” เหมาะสำหรับการทดลอง; ให้ทำการลิขสิทธิ์เซิร์ฟเวอร์ก่อนที่ไฟล์ใดจะออกจากทีม
  • เทมเพลตเป็นอินพุตที่เชื่อถือได้ แท็กรูปภาพและเอกสารจะโหลดเส้นทางและ URL ที่ผลลัพธ์ของนิพจน์ของมันคืนค่า, ดังนั้นให้ถือว่าเทมเพลตจาก pull request เหมือนโค้ด, และให้เซิร์ฟเวอร์มีโฟลเดอร์จัดเก็บเดียว
  • วันที่: เขียนเป็น 2026-11-03T00:00:00 และจัดรูปแบบในเทมเพลต (<<[release.Date]:"d MMMM yyyy">>). สตริงที่มีแค่วันที่ถูกเลื่อนหนึ่งวันบนเครื่องที่ใช้ UTC+2 ในการทดสอบของเรา; Docker image ทำงานใน UTC
  • การสร้างต่อบันทึกอ่านเฉพาะ JSON, และ maxDocuments (ค่าเริ่มต้น 100) จะหยุดอาร์เรย์ที่ใหญ่เกินคาดก่อนที่ไฟล์ใดจะถูกเขียน
  • get_template_fields เป็นแบบคงที่: ค่าที่คำนวณภายในการฉาย Select หรือ GroupBy จะไม่ถูกติดตาม

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

Claude Code สามารถสร้าง PDF จาก JSON ใน repository ของฉันได้โดยไม่ต้องใช้บริการคลาวด์หรือไม่?
ได้. เซิร์ฟเวอร์ MCP ทำงานแบบโลคัลเป็นกระบวนการลูกของ Claude Code และอ่านเทมเพลตและ JSON จากโฟลเดอร์ที่คุณชี้ไป

สามารถรันนี้ใน CI ได้หรือไม่?
เซิร์ฟเวอร์เป็น MCP server, ดังนั้นต้องมี MCP client: Claude Code ในโหมด headless, หรือตัวรันเอเจนต์ใด ๆ Docker image (ghcr.io/groupdocs-assembly/assembly-net-mcp) เป็นรูปแบบที่สะดวกสำหรับ pipeline

Word หรือ PDF?
ได้ทั้งสองแบบ หากไม่ระบุ format ผลลัพธ์จะเป็น DOCX เหมือนเทมเพลต; "format":"pdf" จะให้เป็น PDF. get_supported_formats แสดงรายการเป้าหมายทั้งหมดต่อเทมเพลต

ไปลึกกว่า