Форматирование текста в PDF с помощью Python
Межстрочный и межсимвольный интервал
Использование межстрочного интервала
Как задать пользовательский межстрочный интервал в PDF на Python — простой случай
Aspose.PDF for Python демонстрирует простой способ управления компоновкой и читаемостью текста через настройку межстрочного интервала.
В приведённом ниже фрагменте кода показано, как управлять межстрочным интервалом в PDF-документе. Код считывает текст из файла (или использует резервное сообщение), применяет выбранный размер шрифта и межстрочный интервал, после чего добавляет отформатированный текст на новую страницу PDF.
- Создайте новый PDF-документ.
- Загрузите исходный текст.
- Инициализируйте объект
TextFragmentи присвойте ему загруженный текст. - Задайте свойства шрифта и интервала:
- Размер шрифта: 12 пунктов
- Межстрочный интервал: 16 пунктов
- Добавьте текстовый фрагмент в коллекцию абзацев страницы.
- Сохраните документ.
import aspose.pdf as ap
import sys
from os import path
def specify_line_spacing_simple_case(outfile):
document = ap.Document()
page = document.pages.add()
lorem_path = path.join(DATA_DIR, "lorem.txt")
if path.exists(lorem_path):
with open(lorem_path, "r", encoding="utf-8") as f:
text = f.read()
else:
text = "Lorem ipsum text not found."
text_fragment = ap.text.TextFragment(text)
text_fragment.text_state.font_size = 12
text_fragment.text_state.line_spacing = 16
page.paragraphs.add(text_fragment)
document.save(outfile)
Как задать пользовательский межстрочный интервал в PDF на Python — особый случай
Рассмотрим применение разных режимов межстрочного интервала с использованием пользовательского шрифта TrueType (TTF).
Код загружает текст из файла, встраивает указанный шрифт и дважды выводит один и тот же текст на странице PDF — каждый раз с другим режимом межстрочного интервала:
FONT_SIZE— межстрочный интервал равен размеру шрифта.FULL_SIZE— межстрочный интервал учитывает полную высоту шрифта (включая верхние и нижние выносные элементы).
import aspose.pdf as ap
import sys
from os import path
def specify_line_spacing_specific_case(outfile):
document = ap.Document()
page = document.pages.add()
font_file = path.join(DATA_DIR, "HPSimplified.ttf")
lorem_path = path.join(DATA_DIR, "lorem.txt")
if path.exists(lorem_path):
with open(lorem_path, "r", encoding="utf-8") as f:
text = f.read()
else:
text = "Lorem ipsum text not found."
with open(font_file, "rb") as font_stream:
font = ap.text.FontRepository.open_font(font_stream, ap.text.FontTypes.TTF)
fragment1 = ap.text.TextFragment(text)
fragment1.text_state.font = font
fragment1.text_state.formatting_options = ap.text.TextFormattingOptions()
fragment1.text_state.formatting_options.line_spacing = (
ap.text.TextFormattingOptions.LineSpacingMode.FONT_SIZE
)
page.paragraphs.add(fragment1)
fragment2 = ap.text.TextFragment(text)
fragment2.text_state.font = font
fragment2.text_state.formatting_options = ap.text.TextFormattingOptions()
fragment2.text_state.formatting_options.line_spacing = (
ap.text.TextFormattingOptions.LineSpacingMode.FULL_SIZE
)
page.paragraphs.add(fragment2)
document.save(outfile)

Использование межсимвольного интервала
Управление межсимвольным интервалом с помощью класса TextFragment
Межсимвольный интервал определяет расстояние между отдельными символами в строке — полезно для тонкой настройки внешнего вида текста или достижения определённых типографических эффектов.
import aspose.pdf as ap
import sys
from os import path
def character_spacing_using_text_fragment(outfile):
document = ap.Document()
page = document.pages.add()
def make_fragment(spacing):
fragment = ap.text.TextFragment("Sample Text with character spacing")
fragment.text_state.font = ap.text.FontRepository.find_font("Arial")
fragment.text_state.font_size = 14
fragment.text_state.character_spacing = spacing
return fragment
page.paragraphs.add(make_fragment(2.0))
page.paragraphs.add(make_fragment(1.0))
page.paragraphs.add(make_fragment(0.75))
document.save(outfile)

Управление межсимвольным интервалом с помощью TextParagraph и TextBuilder
Aspose.PDF позволяет задавать межсимвольный интервал при добавлении текста через TextParagraph и TextBuilder.
Это особенно удобно, когда требуется точный контроль над размещением и переносом текста.
import aspose.pdf as ap
import sys
from os import path
def character_spacing_using_text_paragraph(outfile):
document = ap.Document()
page = document.pages.add()
builder = ap.text.TextBuilder(page)
paragraph = ap.text.TextParagraph()
paragraph.rectangle = ap.Rectangle(100, 700, 500, 750, True)
paragraph.formatting_options.wrap_mode = (
ap.text.TextFormattingOptions.WordWrapMode.BY_WORDS
)
fragment = ap.text.TextFragment("Sample Text with character spacing")
fragment.text_state.font = ap.text.FontRepository.find_font("Arial")
fragment.text_state.font_size = 14
fragment.text_state.character_spacing = 2.0
paragraph.append_line(fragment)
builder.append_paragraph(paragraph)
document.save(outfile)
Создание списков
При работе с PDF-файлами часто требуется выводить структурированную информацию — маркированные, нумерованные списки, а также списки в формате HTML или LaTeX.
Aspose.PDF for Python via .NET предоставляет несколько гибких способов создания и форматирования списков.
Создание маркированного списка
import aspose.pdf as ap
import sys
from os import path
def create_bullet_list(outfile):
document = ap.Document()
page = document.pages.add()
items = [
"First item in the list",
"Second item with more text to demonstrate wrapping behavior.",
"Third item",
"Fourth item",
]
builder = ap.text.TextBuilder(page)
paragraph = ap.text.TextParagraph()
paragraph.rectangle = ap.Rectangle(80, 200, 400, 800, True)
paragraph.formatting_options.wrap_mode = (
ap.text.TextFormattingOptions.WordWrapMode.BY_WORDS
)
for item in items:
fragment = ap.text.TextFragment("• " + item)
fragment.text_state.font = ap.text.FontRepository.find_font("Times New Roman")
fragment.text_state.font_size = 12
paragraph.append_line(fragment)
builder.append_paragraph(paragraph)
document.save(outfile)
Создание нумерованного списка
import aspose.pdf as ap
import sys
from os import path
def create_numbered_list(outfile):
document = ap.Document()
page = document.pages.add()
items = [
"First item in the list",
"Second item with more text to demonstrate wrapping behavior.",
"Third item",
"Fourth item",
]
builder = ap.text.TextBuilder(page)
paragraph = ap.text.TextParagraph()
paragraph.rectangle = ap.Rectangle(80, 200, 400, 800, True)
paragraph.formatting_options.wrap_mode = (
ap.text.TextFormattingOptions.WordWrapMode.BY_WORDS
)
for i, item in enumerate(items):
fragment = ap.text.TextFragment(f"{i + 1}. {item}")
fragment.text_state.font = ap.text.FontRepository.find_font("Times New Roman")
fragment.text_state.font_size = 12
paragraph.append_line(fragment)
builder.append_paragraph(paragraph)
document.save(outfile)
Создание нумерованного списка через HTML
import aspose.pdf as ap
import sys
from os import path
def create_numbered_list_html_version(outfile):
document = ap.Document()
page = document.pages.add()
items = [
"First item in the list",
"Second item with more text to demonstrate wrapping behavior.",
"Third item",
"Fourth item",
]
html_list = "<ol>" + "".join([f"<li>{item}</li>" for item in items]) + "</ol>"
html_fragment = ap.HtmlFragment(html_list)
page.paragraphs.add(html_fragment)
document.save(outfile)

Создание маркированного списка через HTML
import aspose.pdf as ap
import sys
from os import path
def create_bullet_list_html_version(outfile):
document = ap.Document()
page = document.pages.add()
items = [
"First item in the list",
"Second item with more text to demonstrate wrapping behavior.",
"Third item",
"Fourth item",
]
html_list = "<ul>" + "".join([f"<li>{item}</li>" for item in items]) + "</ul>"
html_fragment = ap.HtmlFragment(html_list)
page.paragraphs.add(html_fragment)
document.save(outfile)

Создание маркированного списка через LaTeX
import aspose.pdf as ap
import sys
from os import path
def create_bullet_list_latex_version(outfile):
document = ap.Document()
page = document.pages.add()
items = [
"First item",
"Second item with more text to demonstrate wrapping behavior.",
"Third item",
"Fourth item",
]
tex_list = (
"Lists are easy to create: \\begin{itemize}"
+ "".join([f"\\item {i}" for i in items])
+ "\\end{itemize}"
)
tex_fragment = ap.TeXFragment(tex_list)
page.paragraphs.add(tex_fragment)
document.save(outfile)

Создание нумерованного списка через LaTeX
import aspose.pdf as ap
import sys
from os import path
def create_numbered_list_latex_version(outfile):
document = ap.Document()
page = document.pages.add()
items = [
"First item",
"Second item with more text to demonstrate wrapping behavior.",
"Third item",
"Fourth item",
]
tex_list = (
"Lists are easy to create: \\begin{enumerate}"
+ "".join([f"\\item {i}" for i in items])
+ "\\end{enumerate}"
)
tex_fragment = ap.TeXFragment(tex_list)
page.paragraphs.add(tex_fragment)
document.save(outfile)

Сноски и концевые сноски
Добавление сносок
import aspose.pdf as ap
import sys
from os import path
def add_footnote(outfile):
document = ap.Document()
page = document.pages.add()
text_fragment = ap.text.TextFragment("This is a sample text with a footnote.")
text_fragment.text_state.font = ap.text.FontRepository.find_font("Arial")
text_fragment.text_state.font_size = 14
text_fragment.foot_note = ap.Note("This is the footnote content.")
page.paragraphs.add(text_fragment)
inline_text = ap.text.TextFragment(
" This is another text after footnote in the same paragraph."
)
inline_text.is_in_line_paragraph = True
inline_text.text_state.font = ap.text.FontRepository.find_font("Arial")
inline_text.text_state.font_size = 14
page.paragraphs.add(inline_text)
document.save(outfile)
Сноска с пользовательским стилем текста
import aspose.pdf as ap
import sys
from os import path
def add_footnote_custom_text_style(outfile):
document = ap.Document()
page = document.pages.add()
text_fragment = ap.text.TextFragment("This is a sample text with a footnote.")
text_fragment.text_state.font = ap.text.FontRepository.find_font("Arial")
text_fragment.text_state.font_size = 14
note = ap.Note("This is the footnote content with custom text style.")
note.text_state = ap.text.TextState()
note.text_state.font = ap.text.FontRepository.find_font("Times New Roman")
note.text_state.font_size = 10
note.text_state.foreground_color = ap.Color.red
note.text_state.font_style = ap.text.FontStyles.ITALIC
text_fragment.foot_note = note
page.paragraphs.add(text_fragment)
another_text = ap.text.TextFragment(" This is another text without footnote.")
another_text.text_state.font = ap.text.FontRepository.find_font("Arial")
another_text.text_state.font_size = 14
page.paragraphs.add(another_text)
document.save(outfile)
Сноски с пользовательскими символами-маркерами
import aspose.pdf as ap
import sys
from os import path
def add_footnote_custom_text(outfile):
document = ap.Document()
page = document.pages.add()
text_fragment = ap.text.TextFragment("This is a sample text with a footnote.")
text_fragment.text_state.font = ap.text.FontRepository.find_font("Arial")
text_fragment.text_state.font_size = 14
note = ap.Note("This is the footnote content with custom text style.")
note.text = "*"
text_fragment.foot_note = note
page.paragraphs.add(text_fragment)
# ... (остальной код аналогичен)
document.save(outfile)
Сноски с пользовательским стилем линии
import aspose.pdf as ap
import sys
from os import path
def add_footnote_with_custom_line_style(outfile):
document = ap.Document()
page = document.pages.add()
# Настройка стиля линии
graph_info = ap.GraphInfo()
graph_info.line_width = 2
graph_info.color = ap.Color.red
graph_info.dash_array = [3]
graph_info.dash_phase = 1
page.note_line_style = graph_info
text1 = ap.text.TextFragment("This is a sample text with a footnote.")
text1.foot_note = ap.Note("foot note for text 1")
page.paragraphs.add(text1)
text2 = ap.text.TextFragment("This is yet another sample text with a footnote.")
text2.foot_note = ap.Note("foot note for text 2")
page.paragraphs.add(text2)
document.save(outfile)
Сноска с изображением и таблицей
import aspose.pdf as ap
import sys
from os import path
def add_footnote_with_image_and_table(outfile):
document = ap.Document()
page = document.pages.add()
text = ap.text.TextFragment("This is a sample text with a footnote.")
page.paragraphs.add(text)
note = ap.Note()
# Изображение
image_note = ap.Image()
image_note.file = path.join(DATA_DIR, "logo.jpg")
image_note.fix_height = 20
image_note.fix_width = 20
note.paragraphs.add(image_note)
# Текст
text_note = ap.text.TextFragment("This is the footnote content.")
text_note.text_state.font_size = 20
text_note.is_in_line_paragraph = True
note.paragraphs.add(text_note)
# Таблица
table = ap.Table()
table.rows.add().cells.add("Cell 1,1")
table.rows.add().cells.add("Cell 1,2")
note.paragraphs.add(table)
text.foot_note = note
document.save(outfile)
Добавление концевых сносок (Endnotes)
import aspose.pdf as ap
import sys
from os import path
def add_endnote(outfile):
document = ap.Document()
page = document.pages.add()
text_fragment = ap.text.TextFragment("This is a sample text with an endnote.")
text_fragment.text_state.font = ap.text.FontRepository.find_font("Arial")
text_fragment.text_state.font_size = 14
text_fragment.end_note = ap.Note("This is the EndNote content.")
page.paragraphs.add(text_fragment)
# ... (добавление длинного текста для имитации документа)
document.save(outfile)
Компоновка и управление страницами
Принудительное начало таблицы на новой странице
import aspose.pdf as ap
import sys
from os import path
def force_new_page(output_file_name):
document = ap.Document()
page = document.pages.add()
table = ap.Table()
table.column_widths = "150 150 150"
table.default_cell_border = ap.BorderInfo(ap.BorderSide.ALL)
for i in range(5):
row = table.rows.add()
row.cells.add(f"Row {i + 1} - Col 1")
row.cells.add(f"Row {i + 1} - Col 2")
row.cells.add(f"Row {i + 1} - Col 3")
table.is_in_new_page = True # Ключевой момент
page.paragraphs.add(table)
document.save(output_file_name)
Использование свойства is_in_line_paragraph
import aspose.pdf as ap
import sys
from os import path
def using_inline_paragraph_property(output_file_name):
document = ap.Document()
page = document.pages.add()
fragment1 = ap.text.TextFragment("This is the first part of the paragraph. ")
fragment1.text_state.font = ap.text.FontRepository.find_font("Arial")
fragment1.text_state.font_size = 14
page.paragraphs.add(fragment1)
image = ap.Image()
image.is_in_line_paragraph = True
image.file = path.join(DATA_DIR, "logo.jpg")
image.fix_height = 30
image.fix_width = 30
page.paragraphs.add(image)
fragment2 = ap.text.TextFragment("This is the second part of the same paragraph.")
fragment2.is_in_line_paragraph = True
fragment2.text_state.font = ap.text.FontRepository.find_font("Arial")
fragment2.text_state.font_size = 14
page.paragraphs.add(fragment2)
fragment3 = ap.text.TextFragment("This is a new paragraph.")
fragment3.text_state.font = ap.text.FontRepository.find_font("Arial")
fragment3.text_state.font_size = 14
page.paragraphs.add(fragment3)
document.save(output_file_name)
Создание многостолбцового PDF
import aspose.pdf as ap
import sys
from os import path
def create_multi_column_pdf(output_file_name):
document = ap.Document()
document.page_info.margin.left = 40
document.page_info.margin.right = 40
page = document.pages.add()
# ... (код с FloatingBox, колонками, HTML и т.д.)
document.save(output_file_name)
Пользовательские позиции табуляции (Tab Stops)
import aspose.pdf as ap
import sys
from os import path
def custom_tab_stops(output_file_name):
document = ap.Document()
page = document.pages.add()
tab_stops = ap.text.TabStops()
tab_stop1 = tab_stops.add(100)
tab_stop1.alignment_type = ap.text.TabAlignmentType.RIGHT
tab_stop1.leader_type = ap.text.TabLeaderType.SOLID
# ... (добавление остальных табуляций)
header = ap.text.TextFragment(
"This is an example of forming table with TAB stops", tab_stops
)
# ... (остальные фрагменты)
page.paragraphs.add(header)
# ...
document.save(output_file_name)