จัดการฟิลด์ข้อความในงานนำเสนอ PowerPoint ด้วย Python ผ่าน Java
ภาพรวม
ย่อหน้าข้อความประกอบด้วยส่วนต่าง ๆ ส่วนธรรมดา Portion มีข้อความตามตัวอักษร; ส่วนฟิลด์ยังมี Field ที่ประเภทระบุมูลค่าที่อัปเดตอัตโนมัติ เช่นหมายเลขสไลด์หรือวันที่ สองส่วนสามารถแสดงอักขระเดียวกันได้แต่เฉพาะส่วนหนึ่งเท่านั้นที่มีฟิลด์
ใช้ Portion.getField เพื่อแยกแยะ: ค่าจะเป็น None สำหรับข้อความธรรมดา Portion.addField จะแปลงส่วนที่มีอยู่ให้เป็นฟิลด์ เก็บป้ายกำกับและค่าที่เปลี่ยนแปลงได้ในส่วนแยกกันเพื่อให้การแปลงค่าจะไม่ไปแทนที่ป้ายกำกับด้วย
คู่มือฉบับนี้ครอบคลุมฟิลด์ภายในข้อความ การจัดรูปแบบของฟิลด์ และการบันทึกเป็นไฟล์ PPTX และ PPT สำหรับกรอบข้อความและย่อหน้า ดูที่ Manage Text
สร้างฟิลด์หมายเลขสไลด์
ตัวอย่างเต็มต่อไปนี้สร้างกล่องข้อความที่มีป้ายกำกับตามตัวอักษร Slide ตามด้วยหมายเลขที่อัปเดตอัตโนมัติ มันตั้งขนาด น้ำหนัก และสีของหมายเลขก่อนเพิ่มฟิลด์ จากนั้นเปิดการนำเสนอที่บันทึกใหม่อีกครั้งและตรวจสอบประเภทฟิลด์ ข้อความ และการจัดรูปแบบ ไม่ต้องใช้ไฟล์อินพุต
import jpype
import asposeslides
if not jpype.isJVMStarted():
jpype.startJVM()
from asposeslides.api import Presentation, Portion, ShapeType, NullableBool, FillType, FieldType, SaveFormat
from java.awt import Color
presentation = Presentation()
try:
slide = presentation.getSlides().get_Item(0)
shape = slide.getShapes().addAutoShape(ShapeType.Rectangle, 40, 40, 240, 50)
shape.addTextFrame("Slide ")
paragraph = shape.getTextFrame().getParagraphs().get_Item(0)
number_portion = Portion()
number_color = Color(0, 0, 139)
number_portion.getPortionFormat().setFontHeight(24)
number_portion.getPortionFormat().setFontBold(NullableBool.True_)
number_portion.getPortionFormat().getFillFormat().setFillType(FillType.Solid)
number_portion.getPortionFormat().getFillFormat().getSolidFillColor().setColor(number_color)
paragraph.getPortions().add(number_portion)
number_portion.addField(FieldType.getSlideNumber())
presentation.save("slide_number.pptx", SaveFormat.Pptx)
reopened = Presentation("slide_number.pptx")
try:
saved_shape = reopened.getSlides().get_Item(0).getShapes().get_Item(0)
saved_number = saved_shape.getTextFrame().getParagraphs().get_Item(0).getPortions().get_Item(1)
saved_field = saved_number.getField()
has_number_field = saved_field is not None and saved_field.getType().getInternalString() == FieldType.getSlideNumber().getInternalString()
portion_format = saved_number.getPortionFormat()
formatting_preserved = portion_format.getFontHeight() == 24 and portion_format.getFontBold() == NullableBool.True_
formatting_preserved = formatting_preserved and portion_format.getFillFormat().getSolidFillColor().getColor().getRGB() == number_color.getRGB()
print(f"Text: {saved_shape.getTextFrame().getText()}")
print(f"Slide number field: {has_number_field}")
print(f"Formatting preserved: {formatting_preserved}")
finally:
reopened.dispose()
finally:
presentation.dispose()
การนำเสนอใหม่เริ่มต้นที่หมายเลขสไลด์ 1 ดังนั้นข้อความจะเป็น Slide 1 และการตรวจสอบทั้งสองจะแสดงผล True หมายเลขยังคงเป็นฟิลด์หลังจากเปิดใหม่; ไม่ใช่ข้อความตามตัวอักษร 1 ดัชนีในขั้นตอนตรวจสอบอ้างอิงถึงรูปร่างและส่วนที่สร้างโดยตัวอย่างนี้
เลือกประเภทฟิลด์
FieldType ให้วิธีต่อไปนี้สำหรับการรับค่าที่กำหนดไว้ล่วงหน้า ส่งค่าที่เหมาะสมไปยัง addField
| วิธี | วัตถุประสงค์ |
|---|---|
| getSlideNumber | หมายเลขสไลด์ปัจจุบัน |
| getDateTime | วันที่/เวลาในรูปแบบค่าเริ่มต้นของแอปพลิเคชันที่แสดงผล |
| getDateTime1–getDateTime9 | รูปแบบวันที่หรือวันที่/เวลาที่กำหนดไว้ล่วงหน้า |
| getDateTime10–getDateTime13 | รูปแบบเวลาแบบกำหนดไว้ล่วงหน้า มีตัวเลือกสำหรับวินาทีและรูปแบบนาฬิกา 12 ชั่วโมง |
| getHeader | ฟิลด์หัวเรื่อง; ดูข้อจำกัดของตัวยึดตำแหน่งและรูปแบบต่อไปนี้ |
| getFooter | ฟิลด์ท้ายกระดาษ |
ตัวอย่างเช่น getDateTime3 แสดงวัน เดือนเต็มเป็นภาษาอังกฤษและปี นี่เป็นรูปแบบฟิลด์ที่กำหนดไว้ล่วงหน้า ไม่ใช่สตริงรูปแบบวันที่ของ Python ภาษา ที่ตั้งด้วย setLanguageId และแอปพลิเคชันที่ประมวลผลการนำเสนออาจส่งผลต่อผลลัพธ์ที่แสดง
สร้างฟิลด์จากสตริงภายใน
การโอเวอร์โหลดด้วยสตริงของ addField ยอมรับตัวระบุฟิลด์ภายใน ใช้เมื่อเก็บตัวระบุที่ให้มาจากแอปพลิเคชันอื่นที่ไม่มีค่าที่กำหนดไว้ล่วงหน้า คุณยังสามารถสร้าง FieldType จากตัวระบุนั้นได้ FieldType.getInternalString จะเปิดเผยตัวระบุเพื่อการตรวจสอบ
ตัวอย่างนี้เก็บฟิลด์เฉพาะแอป custom-report-id พร้อมข้อความสำรอง Report-042 ตัวระบุตัวนี้ไม่ได้ลงทะเบียนการคำนวน: Aspose.Slides จะไม่สร้างรหัสรายงานสำหรับประเภทที่ไม่รู้จัก แอปที่เข้าใจตัวระบุตัวนี้ต้องจัดหาความหมายและอัปเดตค่าของมัน
import jpype
import asposeslides
if not jpype.isJVMStarted():
jpype.startJVM()
from asposeslides.api import Presentation, ShapeType, SaveFormat
presentation = Presentation()
try:
shape = presentation.getSlides().get_Item(0).getShapes().addAutoShape(ShapeType.Rectangle, 40, 40, 300, 50)
shape.addTextFrame("Report-042")
portion = shape.getTextFrame().getParagraphs().get_Item(0).getPortions().get_Item(0)
portion.addField("custom-report-id")
presentation.save("custom_field.pptx", SaveFormat.Pptx)
reopened = Presentation("custom_field.pptx")
try:
saved_shape = reopened.getSlides().get_Item(0).getShapes().get_Item(0)
saved_portion = saved_shape.getTextFrame().getParagraphs().get_Item(0).getPortions().get_Item(0)
saved_field = saved_portion.getField()
type_name = "ordinary text" if saved_field is None else saved_field.getType().getInternalString()
print(f"Type: {type_name}")
print(f"Text: {saved_portion.getText()}")
finally:
reopened.dispose()
finally:
presentation.dispose()
หลังการวนรอบ PPTX ประเภทจะเป็น custom-report-id และข้อความเป็น Report-042 การส่งสตริงเช่น yyyy-MM-dd จะตั้งชื่อประเภทฟิลด์; ไม่ได้ตั้งค่ารูปแบบวันที่แบบกำหนดเอง สำหรับวันที่คงที่ในรูปแบบใดก็ได้ ให้ใช้ข้อความธรรมดา
ตรวจสอบ แก้ไข และลบฟิลด์วันที่/เวลา
เปลี่ยนฟิลด์ที่มีอยู่ผ่าน Field.setType ตรวจสอบว่าฟิลด์มีอยู่ก่อนเข้าถึงประเภทของมัน เพื่อหยุดการอัปเดตอัตโนมัติ ให้เรียก Portion.removeField ซึ่งจะคงส่วนและข้อความปัจจุบันไว้ขณะลบการเชื่อมโยงฟิลด์ หากต้องการค่าคงที่เฉพาะ ให้กำหนดข้อความนั้นหลังจากลบฟิลด์
สำหรับการตั้งค่า API ที่เกี่ยวข้องกับการประมวลผลฟิลด์วันที่/เวลา ดูที่ Presentation.setCurrentDateTime ตัวอย่างด้านล่างใช้วันที่การอนุมัติที่ระบุชัดเจนเมื่อแปลงฟิลด์เป็นข้อความธรรมดา
ดาวน์โหลด sample.pptx แล้ววางไว้ในไดเรกทอรีทำงานไฟล์นี้มีรูปร่างข้อความที่ตั้งชื่อ UpdatedAt และ ApprovedDate แต่ละรูปร่างมีฟิลด์วันที่/เวลา รวมถึงป้ายกำกับข้อความธรรมดา ตัวอย่างต่อไปนี้วนหารูปร่างข้อความระดับบนบนสไลด์ปกติ เปลี่ยนฟิลด์วันที่/เวลาเป็นรูปแบบวันที่ยาวและทำให้เป็นอิตาลิก พร้อมคงการจัดรูปแบบอื่นไว้ ฟิลด์ใน ApprovedDate จะถูกแปลงเป็นข้อความคงที่
import re
from datetime import date
import jpype
import asposeslides
if not jpype.isJVMStarted():
jpype.startJVM()
from asposeslides.api import Presentation, AutoShape, FieldType, NullableBool, SaveFormat
presentation = Presentation("sample.pptx")
try:
approval_date = date(2030, 4, 5)
# ใช้ชื่อเดือนภาษาอังกฤษโดยไม่ขึ้นกับค่าภาษาในระบบ.
month_names = ("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December")
fixed_date = f"{approval_date.day:02d} {month_names[approval_date.month - 1]} {approval_date.year}"
for slide in presentation.getSlides():
for shape in slide.getShapes():
if not isinstance(shape, AutoShape):
continue
if shape.getTextFrame() is None:
continue
for paragraph in shape.getTextFrame().getParagraphs():
for portion in paragraph.getPortions():
field = portion.getField()
if field is None:
continue
type_name = field.getType().getInternalString()
is_date_time = type_name is not None and re.fullmatch(r"datetime([1-9]|1[0-3])?", str(type_name)) is not None
if not is_date_time:
continue
field.setType(FieldType.getDateTime3())
portion.getPortionFormat().setLanguageId("en-US")
portion.getPortionFormat().setFontItalic(NullableBool.True_)
if shape.getName() == "ApprovedDate":
portion.removeField()
portion.setText(fixed_date)
presentation.save("updated_dates.pptx", SaveFormat.Pptx)
reopened = Presentation("updated_dates.pptx")
try:
for shape in reopened.getSlides().get_Item(0).getShapes():
if not isinstance(shape, AutoShape):
continue
if shape.getTextFrame() is None:
continue
if shape.getName() not in ("UpdatedAt", "ApprovedDate"):
continue
portion = shape.getTextFrame().getParagraphs().get_Item(0).getPortions().get_Item(0)
field = portion.getField()
type_name = "ordinary text" if field is None else field.getType().getInternalString()
print(f"{shape.getName()}: {type_name}; {portion.getText()}")
print(f"Italic: {portion.getPortionFormat().getFontItalic()}")
finally:
reopened.dispose()
finally:
presentation.dispose()
หลังจากเปิดใหม่ UpdatedAt มีประเภท datetime3 และยังคงเป็นค่าที่เปลี่ยนแปลงได้ ApprovedDate ไม่มีฟิลด์และมีข้อความ 05 April 2030 ทั้งสองส่วนวันที่เป็นอิตาลิก และขนาดฟอนต์ น้ำหนักตัวหนา และสีดั้งเดิมยังคงอยู่ ป้ายกำกับข้อความธรรมดาไม่เปลี่ยนแปลง การตรวจสอบอ่านส่วนแรกของสองรูปร่างที่รู้จักในตัวอย่างที่ให้มา
คงรูปแบบข้อความ
ทำงานกับส่วนที่มีอยู่เมื่อต้องเพิ่มฟิลด์ เปลี่ยนประเภทฟิลด์ หรือกำจัดฟิลด์ การทำเช่นนี้จะรักษาการจัดรูปแบบของส่วนนั้น ใช้ Portion.getPortionFormat เพื่อเปลี่ยนเฉพาะคุณสมบัติตามที่ต้องการ เหมือนที่ตัวอย่างทำสำหรับสีหรืออิตาลิก
หลีกเลี่ยงการสร้างกรอบข้อความใหม่ทั้งหมดเพียงเพื่ออัปเดตฟิลด์เดียว: การทำเช่นนั้นอาจทำให้ขอบเขตส่วนเดิมและการจัดรูปแบบแยกของแต่ละส่วนหายไป และให้แยกความแตกต่างระหว่างการกำหนดรูปแบบโดยตรงกับรูปแบบที่สืบทอดมาจากย่อหน้า เลย์เอาต์ หรือธีม ดูที่ Text Formatting สำหรับตัวเลือกการจัดรูปแบบที่ครอบคลุมกว่า
ฟิลด์และตัวยึดตำแหน่งหัวเรื่อง/ท้ายกระดาษ
ฟิลด์เป็นส่วนหนึ่งของส่วนข้อความ ตัวยึดตำแหน่งเป็นรูปร่างที่มีบทบาทในงานนำเสนอ เช่นท้ายกระดาษหรือหมายเลขสไลด์ การเพิ่มฟิลด์ในกล่องข้อความธรรมดาจะไม่ทำให้รูปร่างนั้นกลายเป็นตัวยึดตำแหน่ง
ตัวจัดการหัวเรื่อง/ท้ายกระดาษควบคุมข้อความตัวยึดตำแหน่งและการมองเห็นบนสไลด์, เลย์เอาต์และมาสเตอร์ รวมถึงการกระจายไปยังสไลด์ที่ขึ้นต่อกัน ฟิลด์หมายเลขในกล่องข้อความกำหนดเองจึงอาจมีประโยชน์แม้ไม่ได้ใช้ตัวยึดตำแหน่งหมายเลขสไลด์ อย่างไรก็ตาม การเปลี่ยนการมองเห็นของตัวยึดตำแหน่งจะไม่ลบฟิลด์ออกจากกล่องข้อความที่ไม่มีความเกี่ยวข้อง
ประเภทหัวเรื่องและท้ายกระดาษที่กำหนดไว้ล่วงหน้าไม่ได้สร้างตัวยึดตำแหน่งที่สอดคล้องหรือให้เนื้อหาที่กำหนดไว้ โดยเฉพาะสไลด์ PowerPoint ปกติไม่มีตัวยึดตำแหน่งหัวเรื่อง; หัวเรื่องเป็นส่วนของหน้าบันทึกและเอกสารแจกจ่าย อย่าสันนิษฐานว่าฟิลด์หัวเรื่องหรือท้ายกระดาษในรูปร่างใด ๆ จะได้รับข้อความที่กำหนดผ่านตัวจัดการตัวยึดตำแหน่งโดยอัตโนมัติ สำหรับกระบวนการนั้น ดูที่ Presentation Headers and Footers
ข้อจำกัดของ PPTX และ PPT
ตรวจสอบทั้งประเภทฟิลด์และข้อความที่ได้หลังจากบันทึกและเปิดใหม่ การเก็บตัวระบุไม่ได้พิสูจน์ว่าแอปพลิเคชันสามารถคำนวนหรือแสดงค่าที่ได้
| รูปแบบ | พฤติกรรมของฟิลด์และข้อจำกัด |
|---|---|
| PPTX | เก็บตัวระบุฟิลด์ภายในพร้อมกับข้อความฟิลด์ ในการตรวจสอบรอบการวนกลับ ประเภทที่กำหนดไว้ล่วงหน้าและตัวระบุที่กำหนดเองข้างต้นยังคงอยู่หลังการบันทึกและเปิดใหม่ ฟิลด์ประเภทที่ไม่รู้จักยังคงแสดงข้อความสำรอง; ไม่ได้เพิ่มตรรกะคำนวนอัตโนมัติ แอปอื่นอาจจัดการตัวระบุที่ไม่สนับสนุนต่างกัน |
| PPT | ใช้การแทนฟิลด์แบบเก่าและมีความเข้ากันได้จำกัดกว่า ในการตรวจสอบรอบการวนกลับ หมายเลขสไลด์และฟิลด์วันที่/เวลาที่กำหนดไว้ล่วงหน้ายังคงอยู่หลังการบันทึกและเปิดใหม่ ฟิลด์กำหนดเองในกล่องข้อความสไลด์ธรรมดาจะเปิดใหม่พร้อมตัวระบุแต่ข้อความเป็น *; ฟิลด์หัวเรื่องในบริบทเดียวกันก็เช่นกัน อย่าพึ่งพาฟิลด์กำหนดเองหรือบริบทฟิลด์ที่ไม่สนับสนุนให้คงข้อความที่มองเห็นได้ |
สำหรับผลลัพธ์ที่พกพาและคงที่ ให้แปลงฟิลด์ที่ไม่สนับสนุนเป็นข้อความธรรมดาและกำหนดค่าที่ต้องการอย่างชัดเจนก่อนบันทึก วิธีนี้จะคงข้อความที่เลือกไว้แต่หยุดการอัปเดตอัตโนมัติ ตรวจสอบแอปเป้าหมายด้วยหากการคำนวนฟิลด์ของมันเป็นส่วนหนึ่งของกระบวนการทำงานของคุณ
คำถามที่พบบ่อย
ฉันจะบอกได้อย่างไรว่าตัวเลขหรือวันที่ที่แสดงเป็นฟิลด์หรือไม่?
ตรวจสอบ Portion.getField ค่าที่ไม่ใช่ None ระบุว่ามีฟิลด์; ไม่สามารถบอกได้จากข้อความที่แสดงเพียงอย่างเดียว
การลบฟิลด์จะลบข้อความหรือการจัดรูปแบบของมันด้วยหรือไม่?
ไม่ใช่ removeField จะเปลี่ยนส่วนที่มีอยู่ให้เป็นข้อความธรรมดา หากต้องการค่าที่คงที่ให้กำหนดค่าแบบชัดเจนหลังจากลบฟิลด์
สตริงภายในสามารถกำหนดรูปแบบวันที่ใหม่หรือสูตรใหม่ได้หรือไม่?
ไม่ได้ สตริงภายในเป็นตัวระบุประเภทฟิลด์เท่านั้น ตัวระบุที่ไม่รู้จักไม่ได้มีตัวประเมินหรือรูปแบบวันที่ของ Python ใช้ประเภทที่สนับสนุนหรือจัดรูปแบบค่าด้วยข้อความธรรมดา
ทำไมต้องตรวจสอบงานนำเสนออีกครั้งหลังจากบันทึก?
ตัวระบุฟิลด์, ข้อความที่คำนวนได้, และการจัดรูปแบบเป็นสิ่งที่ต้องตรวจสอบแยกกัน การแปลงรูปแบบอาจเปลี่ยนผลลัพธ์ที่มองเห็นได้แม้ว่าตัวระบุฟิลด์ยังคงอยู่ก็ตาม