Hướng dẫn python-pptx replace text keep formatting - python-pptx thay thế văn bản giữ định dạng

Tôi biết câu hỏi này đã cũ, nhưng tôi vừa hoàn thành một dự án sử dụng Python để cập nhật PowerPoint hàng ngày. Về cơ bản mỗi sáng, tập lệnh Python được chạy và nó lấy dữ liệu cho ngày đó từ cơ sở dữ liệu, đặt dữ liệu vào PowerPoint và sau đó thực hiện trình xem PowerPoint để phát PowerPoint.

Để Asnwer câu hỏi của bạn, bạn sẽ phải lặp qua tất cả các hình dạng trên trang và kiểm tra xem chuỗi bạn đang tìm kiếm có ở dạng hình.text không. Bạn có thể kiểm tra xem hình dạng có văn bản không bằng cách kiểm tra nếu hình dạng.has_text_frame có đúng không. Điều này tránh lỗi.

Đây là nơi mọi thứ có được Trickey. Nếu bạn chỉ thay thế chuỗi trong Shape.Text bằng văn bản bạn muốn chèn, có lẽ bạn sẽ định dạng lỏng lẻo. SHAPE.TEXT thực sự là một sự kết hợp của tất cả các văn bản trong hình dạng. Văn bản đó có thể được chia thành rất nhiều 'chạy' và tất cả các lần chạy đó có thể có định dạng khác nhau sẽ bị mất nếu bạn viết qua Shape.Text hoặc thay thế một phần của chuỗi.

Trên slide, bạn có hình dạng và hình dạng có thể có Text_Frame và Text_Frames có đoạn văn (ít nhất là một. Ngay cả khi trống), và các đoạn văn có thể chạy. Bất kỳ cấp độ nào cũng có thể có định dạng và bạn không có cách nào để xác định số lần chạy chuỗi của bạn bị chia tách.

Trong trường hợp của tôi, tôi chắc chắn rằng bất kỳ chuỗi nào sẽ được thay thế đều có hình dạng riêng. Bạn vẫn phải khoan tất cả các cách để chạy và đặt văn bản ở đó để tất cả các định dạng sẽ được bảo tồn. Ngoài ra, chuỗi bạn khớp với hình dạng. Thực sự có thể được trải đều trên nhiều lần chạy, vì vậy khi đặt văn bản trong lần chạy đầu tiên, tôi cũng đặt văn bản trong tất cả các lần chạy khác trong đoạn đó thành trống.

Mã ngẫu nhiên Snippit:

from pptx import Presentation

testString = '{{thingToReplace}}'
replaceString = 'this will be inserted'
ppt = Presentation('somepptxfile.pptx')

def replaceText(shape, string,replaceString):
    #this is the hard part
    #you know the string is in there, but it may be across many runs


for slide in ppt.slides:
    for shape in slide.shapes:
        if shape.has_text_frame:
            if(shape.text.find(testString)!=-1:
                replaceText(shape,testString,replaceString)

Xin lỗi nếu có bất kỳ lỗi chính tả. Tôi đang làm việc.....

Để chỉnh sửa một số văn bản, tôi hiện đang sử dụng Pharagraphs và chạy và áp dụng tất cả các kiểu tôi quan tâm. Sẽ rất thú vị khi có một cách để thay đổi văn bản của một văn bản hiện có, khiến cho định dạng không bị ảnh hưởng.

Hướng dẫn python-pptx replace text keep formatting - python-pptx thay thế văn bản giữ định dạng

@PowAHFTW Định dạng ký tự (Đặc điểm phông chữ) được chỉ định ở cấp độ Run. Một đối tượng Paragraph chứa một hoặc nhiều (thường nhiều hơn) chạy. Khi gán cho

def replace_paragraph_text_retaining_initial_formatting(paragraph, new_text):
    p = paragraph._p  # the lxml element containing the `` paragraph element
    # remove all but the first run
    for idx, run in enumerate(paragraph.runs):
        if idx == 0:
            continue
        p.remove(run._r)
    paragraph.runs[0].text = new_text

paragraph = textframe.paragraph[0]  # or wherever you get the paragraph from
new_text = 'foobar'
replace_paragraph_text_retaining_initial_formatting(paragraph, new_text)
0, tất cả các lần chạy trong đoạn văn được thay thế bằng một lần chạy mới. Đây là lý do tại sao định dạng văn bản biến mất; bởi vì các lần chạy chứa định dạng đó biến mất.

Mặc dù nó sẽ không hoạt động cho tất cả các trường hợp người ta có thể muốn, một hành vi hữu ích sẽ là thay thế văn bản trong một đoạn, giữ lại định dạng có mặt trong lần chạy đầu tiên. Điều này có thể được thực hiện như thế này:

def replace_paragraph_text_retaining_initial_formatting(paragraph, new_text):
    p = paragraph._p  # the lxml element containing the `` paragraph element
    # remove all but the first run
    for idx, run in enumerate(paragraph.runs):
        if idx == 0:
            continue
        p.remove(run._r)
    paragraph.runs[0].text = new_text

paragraph = textframe.paragraph[0]  # or wherever you get the paragraph from
new_text = 'foobar'
replace_paragraph_text_retaining_initial_formatting(paragraph, new_text)

Tôi đã không kiểm tra điều này, có lẽ bạn có thể báo cáo lại bất kỳ sai lầm nào nếu bạn dùng thử, nhưng tôi nghĩ nó mang lại ý chính.

Đây sẽ là cách mà một tính năng như vậy sẽ được thực hiện.

POWAHFTW, ELMUNDIO87, ANTONYFUENTES, PERPERRINO, WASTR, BashSebBash, NicoZHang, DurakKerem, Jospolfliet, OlegSchWann và 8 phản ứng biểu tượng cảm xúc

@Scanny vừa thử chức năng được đề xuất của bạn và nó hoạt động hoàn hảo - cảm ơn!

Wow ... điều này thật hoàn hảo. Tôi đã viết một vòng lặp thử/ngoại trừ việc lưu trữ các thuộc tính của lần chạy đầu tiên và sau đó ứng dụng lại chúng sau khi thay đổi văn bản. Cảm thấy như một người man rợ.

Chào các cậu,

Cảm ơn @Scanny cho đoạn trích! Nó thực sự hữu ích. Tôi đã gặp một cái gì đó kỳ lạ mặc dù. Vì một số lý do không rõ, một số ô trong tệp của tôi mặc dù trông giống như một dòng văn bản duy nhất, nó được chia thành một số

def replace_paragraph_text_retaining_initial_formatting(paragraph, new_text):
    p = paragraph._p  # the lxml element containing the `` paragraph element
    # remove all but the first run
    for idx, run in enumerate(paragraph.runs):
        if idx == 0:
            continue
        p.remove(run._r)
    paragraph.runs[0].text = new_text

paragraph = textframe.paragraph[0]  # or wherever you get the paragraph from
new_text = 'foobar'
replace_paragraph_text_retaining_initial_formatting(paragraph, new_text)
1.
I did encounter something strange though. For some unknown reason(s), some cells in my file despite looking like a single line of text, it was split into a number of
def replace_paragraph_text_retaining_initial_formatting(paragraph, new_text):
    p = paragraph._p  # the lxml element containing the `` paragraph element
    # remove all but the first run
    for idx, run in enumerate(paragraph.runs):
        if idx == 0:
            continue
        p.remove(run._r)
    paragraph.runs[0].text = new_text

paragraph = textframe.paragraph[0]  # or wherever you get the paragraph from
new_text = 'foobar'
replace_paragraph_text_retaining_initial_formatting(paragraph, new_text)
1.

Vì vậy, tôi đã phải sửa đổi đoạn trích của bạn thành cái này

...
whole_text = " ".join([r.text for r in paragraph.runs])
whole_text = re.sub(replacement_string, new_text, whole_text)
    for idx, run in enumerate(paragraph.runs):
        if idx == 0:
            continue
        p = paragraph._p
        p.remove(run._r)
    paragraph.runs[0].text = whole_text
...

Hy vọng điều này sẽ giúp ... hoặc tốt, tôi chỉ muốn chia sẻ giải pháp cho cả buổi sáng của sự thất vọng ...

Điều này thực sự giúp chúng tôi .... Cảm ơn bạn rất nhiều @Scanny

Chào @Scanny,

Cảm ơn vì đoạn trích! Câu hỏi mặc dù - đang thay đổi văn bản trên đoạn văn thực sự được cho là xóa định dạng hay đó là một lỗi?

Cảm ơn

@Franz-See

def replace_paragraph_text_retaining_initial_formatting(paragraph, new_text):
    p = paragraph._p  # the lxml element containing the `` paragraph element
    # remove all but the first run
    for idx, run in enumerate(paragraph.runs):
        if idx == 0:
            continue
        p.remove(run._r)
    paragraph.runs[0].text = new_text

paragraph = textframe.paragraph[0]  # or wherever you get the paragraph from
new_text = 'foobar'
replace_paragraph_text_retaining_initial_formatting(paragraph, new_text)
0 là một tài sản tiện lợi. Không có cách nào trong trường hợp chung để thay đổi văn bản trong khi bảo tồn định dạng. Ví dụ: nếu bạn muốn thay thế:

Chú cáo nâu nhanh nhẹn.quick, brown fox.

with:

Con chó màu vàng lười biếng.dog.

Làm thế nào bạn sẽ làm điều đó với một cái gì đó như

def replace_paragraph_text_retaining_initial_formatting(paragraph, new_text):
    p = paragraph._p  # the lxml element containing the `` paragraph element
    # remove all but the first run
    for idx, run in enumerate(paragraph.runs):
        if idx == 0:
            continue
        p.remove(run._r)
    paragraph.runs[0].text = new_text

paragraph = textframe.paragraph[0]  # or wherever you get the paragraph from
new_text = 'foobar'
replace_paragraph_text_retaining_initial_formatting(paragraph, new_text)
0? Vì vậy, việc gán văn bản cho
def replace_paragraph_text_retaining_initial_formatting(paragraph, new_text):
    p = paragraph._p  # the lxml element containing the `` paragraph element
    # remove all but the first run
    for idx, run in enumerate(paragraph.runs):
        if idx == 0:
            continue
        p.remove(run._r)
    paragraph.runs[0].text = new_text

paragraph = textframe.paragraph[0]  # or wherever you get the paragraph from
new_text = 'foobar'
replace_paragraph_text_retaining_initial_formatting(paragraph, new_text)
0 thay thế tất cả các lần chạy trong đoạn văn bằng một lần chạy duy nhất chứa văn bản được gán không có định dạng đặc biệt.

Định dạng ký tự được cung cấp bởi kiểu đoạn văn được bảo tồn, và nói chung điều này tạo ra kết quả tốt nhất có thể. Nếu bạn cần áp dụng định dạng ký tự "nội tuyến", thì bạn cần phải tự mình thực hiện, chạy.

Một cách để làm điều này là gán

def replace_paragraph_text_retaining_initial_formatting(paragraph, new_text):
    p = paragraph._p  # the lxml element containing the `` paragraph element
    # remove all but the first run
    for idx, run in enumerate(paragraph.runs):
        if idx == 0:
            continue
        p.remove(run._r)
    paragraph.runs[0].text = new_text

paragraph = textframe.paragraph[0]  # or wherever you get the paragraph from
new_text = 'foobar'
replace_paragraph_text_retaining_initial_formatting(paragraph, new_text)
5 cho
def replace_paragraph_text_retaining_initial_formatting(paragraph, new_text):
    p = paragraph._p  # the lxml element containing the `` paragraph element
    # remove all but the first run
    for idx, run in enumerate(paragraph.runs):
        if idx == 0:
            continue
        p.remove(run._r)
    paragraph.runs[0].text = new_text

paragraph = textframe.paragraph[0]  # or wherever you get the paragraph from
new_text = 'foobar'
replace_paragraph_text_retaining_initial_formatting(paragraph, new_text)
6 để "xóa" văn bản hiện có và sau đó thêm các lần chạy vào đoạn văn cho phù hợp.

Điều đó thực sự hữu ích, cảm ơn @Scanny.

Có cách nào để giữ định dạng khi thay thế văn bản trong bảng (ô) không? Thành thật mà nói, tôi không hoàn toàn hiểu mã trên của bạn làm gì, vì vậy tôi đánh giá cao bất kỳ sự giúp đỡ nào.
To be honest, I don't fully understand what your above code does, so I'd appreciate any help.

def replace_text(self, replacements: dict, shapes: list):
    for shape in shapes:
        for match, replacement in replacements.items():
            if shape.has_table:
                for row in shape.table.rows:
                    for cell in row.cells:
                        if match in cell.text:
                            new_text = cell.text.replace(str(match), str(replacement))
                            cell.text = new_text

Từ: https://stackoverflow.com/questions/37924808/python-pptx-power-point-find-and-replace-text-ctrl-h

Tôi nghĩ, tôi đã giải quyết nó. Đó chỉ là vấn đề tìm cách truy cập vào cấp độ

def replace_paragraph_text_retaining_initial_formatting(paragraph, new_text):
    p = paragraph._p  # the lxml element containing the `` paragraph element
    # remove all but the first run
    for idx, run in enumerate(paragraph.runs):
        if idx == 0:
            continue
        p.remove(run._r)
    paragraph.runs[0].text = new_text

paragraph = textframe.paragraph[0]  # or wherever you get the paragraph from
new_text = 'foobar'
replace_paragraph_text_retaining_initial_formatting(paragraph, new_text)
7 cho các ô. Tôi sẽ để giải pháp ở đây trong trường hợp ai đó gặp phải một vấn đề tương tự.

Cảm ơn bạn cho mô -đun tuyệt vời này!

    for shape in shapes:
        for match, replacement in replacements.items():
            if shape.has_table:
                for row in shape.table.rows:
                    for cell in row.cells:
                        if match in cell.text:                                                        
                            for paragraph in cell.text_frame.paragraphs:
                               for run in paragraph.runs:
                                   p = paragraph._p  # the lxml element containing the `` paragraph element
    #                            remove all but the first run
                                   for idx, run in enumerate(paragraph.runs):
                                       if idx == 0:
                                           continue
                                       p.remove(run._r)
                                   cur_text = run.text
                                   new_text = cur_text.replace(str(match), str(replacement))
                                   run.text = new_text

Cùng một mã, được tái cấu trúc một chút cho độ dài và cấp độ thụt. Tôi nghĩ rằng cũng có một lỗi trong đó, bạn đã xóa các lần chạy trước khi ghi lại văn bản chúng chứa.

def iter_table_cells(shapes):
    for shape in shapes:
        if not shape.has_table:
            continue
        for row in shape.table.rows:
            for cell in row.cells:
                yield cell


for cell in iter_table_cells(shapes):
    for match, replacement in replacements.items():
        for paragraph in cell.text_frame.paragraphs:
            if match not in paragraph.text:
                continue
            orig_text = paragraph.text
            # --- the lxml element containing the `` paragraph element ---
            p = paragraph._p
            # --- remove all but the first run ---
            for run in paragraph.runs[1:]:
                p.remove(run._r)
            run = paragraph.runs[0]
            run.text = orig_text.replace(str(match), str(replacement))

Bạn thật tốt bụng. Cảm ơn một lần nữa.

Tôi đang cố gắng làm nổi bật một từ cụ thể có màu đỏ trong tệp pptx bằng cách sử dụng hàm dưới đây.

def highlight_word_in_text(paragraph,highlight_word):
    p = paragraph._p
    paratext = p.text
    if highlight_word in paratext:
        for idx, run in enumerate(paragraph.runs):
            if idx == 0:
                continue
            p.remove(run._r)
        paragraph.runs[0].text = paratext[0:paratext.index(highlight_word)]
        run = paragraph.add_run()
        run.text = paratext[paratext.index(highlight_word):paratext.index(highlight_word)+len(highlight_word)]
        run.font.color.rgb = RGBColor(255, 0, 0)
        run = paragraph.add_run()
        run.text = paratext[paratext.index(highlight_word)+len(highlight_word):]

Trong khi nó hoạt động, nó mất định dạng và cũng thêm một số ký tự bất thường như '_x000B' vào một số từ mà nó tìm thấy từ được tô sáng. Bạn có thể vui lòng cho tôi biết những gì tôi đang thiếu?

Mã đầy đủ bên dưới:

def highlight_word_in_text(paragraph,highlight_word):
    p = paragraph._p
    paratext = p.text
    if highlight_word in paratext:
        for idx, run in enumerate(paragraph.runs):
            if idx == 0:
                continue
            p.remove(run._r)
        paragraph.runs[0].text = paratext[0:paratext.index(highlight_word)]
        run = paragraph.add_run()
        run.text = paratext[paratext.index(highlight_word):paratext.index(highlight_word)+len(highlight_word)]
        run.font.color.rgb = RGBColor(255, 0, 0)
        run = paragraph.add_run()
        run.text = paratext[paratext.index(highlight_word)+len(highlight_word):]
        
prs2 = Presentation('test2.pptx')
for slide in prs2.slides:
    for shape in slide.shapes:
        if not shape.has_text_frame:
            continue
        for paragraph in shape.text_frame.paragraphs:
            highlight_word_in_text(paragraph,'business')
            
prs2.save('test3.pptx')

Làm cách nào để cập nhật tệp python lên pptx?

Bước 1 - Xác định các thành phần tương ứng. Đầu tiên, chúng ta phải quyết định các yếu tố mà chúng ta sẽ cập nhật. ....
Bước 2 - Chuẩn bị dữ liệu. Sau khi hiểu các thành phần để cập nhật, tiếp theo sẽ là nguồn dữ liệu được sử dụng để cập nhật. ....
Bước 3 Cập nhật PowerPoint. Nó đến tập trung của chúng tôi ngày hôm nay ..

Người giữ chỗ trong Python PPTX là gì?

Một trình giữ chỗ cũng có thể được sử dụng để đặt một vật thể có nội dung phong phú trên một slide.Một hình ảnh, bảng hoặc biểu đồ có thể được chèn vào một trình giữ chỗ và do đó đảm nhận vị trí và kích thước của trình giữ chỗ, cũng như một số thuộc tính định dạng của nó.used to place a rich-content object on a slide. A picture, table, or chart can each be inserted into a placeholder and so take on the position and size of the placeholder, as well as certain of its formatting attributes.

Bạn có thể tự động hóa PowerPoint với Python không?

PowerPoint là phần mềm trình bày phổ biến thường được sử dụng cho các chương trình trượt văn phòng và giáo dục.Tạo thuyết trình bằng tay là tốn thời gian.Dự án dựa trên Python này có thể tự động tạo trình bày PowerPoint trong vòng vài phút.This python based project can create PowerPoint presentation automatically within few minutes.

Làm cách nào để lưu pptx dưới dạng pdf trong python?

Sau đây là các bước để chuyển đổi tệp PPT thành PDF trong Python ...
Tải bản trình bày PPT/PPTX bằng lớp trình bày ..
Chuyển đổi PPT thành PDF bằng cách sử dụng trình bày.Lưu (Chuỗi, Xuất. SaveFormat. PDF) Phương thức ..