Я работаю над проектом, в котором мне нужно создать PDF-файл из нескольких файлов SVG. Я решил создать временные PDF-файлы для каждого из файлов SVG, чтобы позже объединить их (возможно, с использованием LaTeX). Я хочу, чтобы окончательный PDF-файл был отформатирован в альбомной ориентации A4 с определенными полями для нечетных и четных страниц. Обратите внимание, что существует очень большое количество этих SVG-файлов, и конечный продукт будет использоваться для печати.
Эти файлы SVG включают в себя:
Я ищу, могу ли я автоматизировать этот процесс с помощью сценария Python или какого-либо инструмента Linux. Буду очень признателен за вашу помощь в данной конкретной ситуации.
Я пробовал использовать Cairosvg и Inkscape, но безуспешно. Есть несколько проблем, с которыми я сталкиваюсь:
--export-area-drawing
, безуспешно)Я использовал этот скрипт Python, но столкнулся с некоторыми проблемами:
svg_files = [f for f in os.listdir(svg_dir) if f.endswith(".svg")]
for svg_file in svg_files:
base_name = os.path.splitext(svg_file)[0]
svg_path = os.path.join(svg_dir, svg_file)
pdf_path = os.path.join(temp_pdf_dir, f"{base_name}.pdf")
subprocess.run(["rsvg-convert", "-f", "pdf", "-o", pdf_path, svg_path])
pdf_files = [
os.path.join(temp_pdf_dir, f)
for f in os.listdir(temp_pdf_dir)
if f.endswith(".pdf")
]
subprocess.run(["pdftk"] + pdf_files + ["cat", "output", final_pdf_path])
Одна из проблем заключается в том, что ни один из шрифтов (ни персидских, ни английских шрифтов) не применяется к выводу. Другая проблема заключалась в изображениях, которые я использовал.
Вот несколько примеров того, как я использовал пользовательские шрифты, градиенты и изображения в своем SVG-файле:
<svg width = "273mm" height = "165mm" xmlns = "http://www.w3.org/2000/svg">
<style>
@font-face {
font-family: "Gungsuh W33 Regular";
src: url("/path/fonts/Gungsuh W33 Regular.woff") format("woff");
}
</style>
<defs>
<pattern id = "imagePattern" patternUnits = "userSpaceOnUse" width = "91mm" height = "55mm">
<image href = "/path/image.svg" x = "0" y = "0" width = "91mm" height = "55mm" />
</pattern>
<linearGradient id = "gradient" x1 = "0%" y1 = "0%" x2 = "100%" y2 = "0%">
<stop offset = "0%" style = "stop-color:rgb(220,50,50); stop-opacity:1" />
<stop offset = "100%" style = "stop-color:rgb(62,62,150); stop-opacity:1" />
</linearGradient>
</defs>
...
<rect x = "182mm" y = "0mm" width = "91mm" height = "55mm" fill = "url(#imagePattern)" />
<text x = "46mm" y = "67.25mm" font-family = "Gungsuh W33 Regular" font-size = "10" letter-spacing = "2.5" fill = "url(#gradient)">
</svg>
Не то чтобы librsvg был очень ясен. НЕ «заменяет промышленные механизмы рендеринга SVG в современных веб-браузерах». github.com/GNOME/…
Спасибо. осознание этого очень помогло. Думаю, мне придется использовать HTML.
Попробуйте изучить Apache FOP: xmlgraphics.apache.org/fop/dev/design/svg.html
Я думаю, что возможным подходом было бы просто создать html-файл, создать 1 или 2 страницы по вашему выбору и попытаться распечатать его с помощью встроенной печати Chrome, чтобы проверить, нравится ли вам стиль, вы можете использовать CSS для полей, и если эти страницы Кажется, вам это нравится, тогда вы можете использовать JS, чтобы сделать эти страницы динамическими, при этом обновляются только svgs. поместите их в один HTML-файл, и я думаю, что касается вашего конечного продукта, существует множество библиотек Python, которые могут конвертировать эти HTML-файлы в PDF-файлы. Это лучшее решение, если что-то ни в чем не поддерживается. вы можете использовать библиотеку Python и организовать ее. Вот демонстрация того, как будет выглядеть код:
import asyncio
from pyppeteer import launch
async def generate_pdf(html_file, pdf_output):
browser = await launch()
page = await browser.newPage()
# Load your HTML file (local or remote)
await page.goto(f'file://{html_file}', {'waitUntil': 'networkidle0'})
# Generate PDF with specific settings
await page.pdf({
'path': pdf_output,
'format': 'A4',
'landscape': True,
'printBackground': True, # Ensures background images and colors are included
'margin': {
'top': '20mm',
'bottom': '20mm',
'left': '25mm',
'right': '25mm'
}
})
await browser.close()
# Run the script
html_path = '/path/to/your/input.html'
output_pdf = '/path/to/your/output.pdf'
asyncio.get_event_loop().run_until_complete(generate_pdf(html_path, output_pdf))
Здесь вам не нужно создавать несколько HTML-файлов, а автоматизировать один HTML-файл, который в конечном итоге может распечатать несколько страниц в одном PDF-файле.
Спасибо за ответ. Я также попробовал этот подход, но он мне не понравился, поскольку это проект печати, и он должен быть очень высокого качества, и, честно говоря, наша команда дизайнеров использует CorelDraw для разработки одной из страниц и предоставления мне вывода в формате SVG. Затем я использую Python для создания нескольких его версий, редактируя цвета, текст и некоторые другие элементы. У меня также есть шрифты с расширением woff и другие изображения в виде файлов SVG в каталогах, и я включил пути в SVG, который создаю с помощью Python.
Привет, если у вас возникла проблема с тем, что шрифт или изображение, которое вы импортируете по пути, не отображаются, вы можете преобразовать эти файлы в двоичную строку base64 и включить ее в путь к файлу, например: <image href = "data:image/png;base64,yourBase64String" />
или для шрифтов вы можете изменить изображение на шрифт и png в woff или другой формат, хотя они могут занимать больше места по сравнению с оригиналом, но это гарантирует правильную загрузку файла. Вы можете использовать библиотеку Python base64
.
Большое спасибо за ваш ответ и комментарий. Думаю, мне все-таки придется заставить его работать с HTML.
PDF не использует графику SVG, а использует альтернативные методы, которые плохо переводятся, если только они не являются очень простыми. Таким образом, шрифты SVG, такие как эмодзи, должны быть преобразованы в изображения поверх обычного текста (очень неэффективно, поскольку возможно использование килобайтов для 1 однобайтового символа). Как и в случае с кругом, в SVG это 1 элемент, но в PDF его должно быть 4, и поэтому он может стать в десятки раз больше. Что касается градиентов, они часто плохо преобразуются во множество полос, а не в собственный объект градиента PDF. Очевидно, что один из более простых методов заключается в том, что SVG - это система HTML, использующая HTML-страницы и позволяющая это сделать эффективному конвертеру HTML в PDF.