Как конвертировать несколько файлов SVG в PDF-файлы

Я работаю над проектом, в котором мне нужно создать PDF-файл из нескольких файлов SVG. Я решил создать временные PDF-файлы для каждого из файлов SVG, чтобы позже объединить их (возможно, с использованием LaTeX). Я хочу, чтобы окончательный PDF-файл был отформатирован в альбомной ориентации A4 с определенными полями для нечетных и четных страниц. Обратите внимание, что существует очень большое количество этих SVG-файлов, и конечный продукт будет использоваться для печати.

Эти файлы SVG включают в себя:

  • Персидские шрифты
  • Некоторые тексты имеют градиент
  • Внешние файлы SVG в качестве фоновых рисунков или даже изображений.

Я ищу, могу ли я автоматизировать этот процесс с помощью сценария Python или какого-либо инструмента Linux. Буду очень признателен за вашу помощь в данной конкретной ситуации.

Я пробовал использовать Cairosvg и Inkscape, но безуспешно. Есть несколько проблем, с которыми я сталкиваюсь:

  • При использовании Cairosvg персидские шрифты не поддерживаются.
  • При использовании Inkscape градиент текста и внешние файлы SVG не экспортируются (я тоже пробовал --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>

🤔 А знаете ли вы, что...
Python используется в научных вычислениях и обработке изображений с использованием библиотеки OpenCV.


1
78
1

Ответ:

Решено

Я думаю, что возможным подходом было бы просто создать 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-файле.