Skip to content

Двостороннє перетворення PDF та документів Office

Конвертуйте документи Microsoft Office (Word, Excel, PowerPoint) у PDF — і перетворюйте PDF назад у DOCX, PPTX або XLSX — без встановлення Microsoft Office чи LibreOffice. PDF Oxide безпосередньо розбирає формат OOXML і генерує PDF, а також рендерить сторінки PDF назад у редаговані документи Office.

Перетворення підтримує два напрямки:

  • Office → PDF — клас OfficeConverter (та конструктори open_from_*_bytes) розбирає DOCX/XLSX/PPTX і генерує PDF.
  • PDF → Office — методи to_docx / to_pptx / to_xlsx на відкритому документі експортують його назад у формати Office.

Швидкий приклад

Python

from pdf_oxide import OfficeConverter

# Auto-detect format from extension
pdf = OfficeConverter.convert("report.docx")
pdf.save("report.pdf")

Rust

use pdf_oxide::converters::office::OfficeConverter;

let converter = OfficeConverter::new();
let pdf_bytes = converter.convert("report.docx")?;
std::fs::write("report.pdf", pdf_bytes)?;

C++

#include <pdf_oxide/pdf_oxide.hpp>
#include <fstream>

std::ifstream in("report.docx", std::ios::binary);
std::vector<std::uint8_t> docx((std::istreambuf_iterator<char>(in)), {});

auto doc = pdf_oxide::Document::open_from_docx_bytes(docx);
auto pdf = doc.get_source_bytes();
std::ofstream("report.pdf", std::ios::binary)
    .write(reinterpret_cast<const char*>(pdf.data()), pdf.size());

Dart

import 'dart:io';
import 'package:pdf_oxide/pdf_oxide.dart';

final docx = File('report.docx').readAsBytesSync();
final doc = PdfDocument.openFromDocxBytes(docx);
File('report.pdf').writeAsBytesSync(doc.getSourceBytes());

R

library(pdfoxide)

docx <- readBin("report.docx", "raw", file.info("report.docx")$size)
doc  <- pdf_open_from_docx_bytes(docx)
writeBin(pdf_get_source_bytes(doc), "report.pdf")

Julia

using PdfOxide

docx = read("report.docx")
doc  = open_from_docx_bytes(docx)
write("report.pdf", get_source_bytes(doc))

Zig

const pdf_oxide = @import("pdf_oxide");
const a = std.heap.page_allocator;

const docx = try std.fs.cwd().readFileAlloc("report.docx", a, .unlimited);
var doc = try pdf_oxide.Document.openFromDocxBytes(docx);
const pdf = try doc.sourceBytes(a);
try std.fs.cwd().writeFile(.{ .sub_path = "report.pdf", .data = pdf });

Objective-C

#import "POXPdfOxide.h"
NSError *err = nil;

NSData *docx = [NSData dataWithContentsOfFile:@"report.docx"];
POXDocument *doc = [POXDocument openFromDocxBytes:docx error:&err];
NSData *pdf = [doc sourceBytesWithError:&err];
[pdf writeToFile:@"report.pdf" atomically:YES];

Elixir

docx = File.read!("report.docx")
{:ok, doc} = PdfOxide.open_from_docx_bytes(docx)
{:ok, pdf} = PdfOxide.source_bytes(doc)
File.write!("report.pdf", pdf)

Підтримувані формати

Формат Розширення Опис
DOCX .docx Документи Word — абзаци, заголовки, списки, форматування тексту
XLSX .xlsx, .xls Таблиці Excel — кілька аркушів, автоматична ширина стовпців, типи комірок
PPTX .pptx Презентації PowerPoint — слайди, заголовки, текстові блоки

Документи Word (DOCX)

Конвертуйте документи Word зі збереженням заголовків, абзаців, списків і форматування тексту (жирний, курсив, підкреслення, кольори, розміри шрифтів).

Python

from pdf_oxide import OfficeConverter

pdf = OfficeConverter.from_docx("document.docx")
pdf.save("document.pdf")

Rust

use pdf_oxide::converters::office::OfficeConverter;

let converter = OfficeConverter::new();
let pdf_bytes = converter.convert_docx("document.docx")?;
std::fs::write("document.pdf", pdf_bytes)?;

C++

#include <pdf_oxide/pdf_oxide.hpp>
#include <fstream>

std::ifstream in("document.docx", std::ios::binary);
std::vector<std::uint8_t> docx((std::istreambuf_iterator<char>(in)), {});

auto doc = pdf_oxide::Document::open_from_docx_bytes(docx);
auto pdf = doc.get_source_bytes();
std::ofstream("document.pdf", std::ios::binary)
    .write(reinterpret_cast<const char*>(pdf.data()), pdf.size());

Dart

import 'dart:io';
import 'package:pdf_oxide/pdf_oxide.dart';

final docx = File('document.docx').readAsBytesSync();
final doc = PdfDocument.openFromDocxBytes(docx);
File('document.pdf').writeAsBytesSync(doc.getSourceBytes());

R

library(pdfoxide)

docx <- readBin("document.docx", "raw", file.info("document.docx")$size)
doc  <- pdf_open_from_docx_bytes(docx)
writeBin(pdf_get_source_bytes(doc), "document.pdf")

Julia

using PdfOxide

docx = read("document.docx")
doc  = open_from_docx_bytes(docx)
write("document.pdf", get_source_bytes(doc))

Zig

const pdf_oxide = @import("pdf_oxide");
const a = std.heap.page_allocator;

const docx = try std.fs.cwd().readFileAlloc("document.docx", a, .unlimited);
var doc = try pdf_oxide.Document.openFromDocxBytes(docx);
const pdf = try doc.sourceBytes(a);
try std.fs.cwd().writeFile(.{ .sub_path = "document.pdf", .data = pdf });

Objective-C

#import "POXPdfOxide.h"
NSError *err = nil;

NSData *docx = [NSData dataWithContentsOfFile:@"document.docx"];
POXDocument *doc = [POXDocument openFromDocxBytes:docx error:&err];
NSData *pdf = [doc sourceBytesWithError:&err];
[pdf writeToFile:@"document.pdf" atomically:YES];

Elixir

docx = File.read!("document.docx")
{:ok, doc} = PdfOxide.open_from_docx_bytes(docx)
{:ok, pdf} = PdfOxide.source_bytes(doc)
File.write!("document.pdf", pdf)

З байтів

Python

from pdf_oxide import OfficeConverter

with open("document.docx", "rb") as f:
    pdf = OfficeConverter.from_docx_bytes(f.read())
pdf.save("document.pdf")

Rust

let docx_bytes = std::fs::read("document.docx")?;
let converter = OfficeConverter::new();
let pdf_bytes = converter.convert_docx_bytes(&docx_bytes)?;
std::fs::write("document.pdf", pdf_bytes)?;

C++

std::ifstream in("document.docx", std::ios::binary);
std::vector<std::uint8_t> docx_bytes((std::istreambuf_iterator<char>(in)), {});

auto doc = pdf_oxide::Document::open_from_docx_bytes(docx_bytes);
auto pdf_bytes = doc.get_source_bytes();
std::ofstream("document.pdf", std::ios::binary)
    .write(reinterpret_cast<const char*>(pdf_bytes.data()), pdf_bytes.size());

Dart

final docxBytes = File('document.docx').readAsBytesSync();
final doc = PdfDocument.openFromDocxBytes(docxBytes);
File('document.pdf').writeAsBytesSync(doc.getSourceBytes());

R

docx_bytes <- readBin("document.docx", "raw", file.info("document.docx")$size)
doc <- pdf_open_from_docx_bytes(docx_bytes)
writeBin(pdf_get_source_bytes(doc), "document.pdf")

Julia

docx_bytes = read("document.docx")
doc = open_from_docx_bytes(docx_bytes)
write("document.pdf", get_source_bytes(doc))

Zig

const docx_bytes = try std.fs.cwd().readFileAlloc("document.docx", a, .unlimited);
var doc = try pdf_oxide.Document.openFromDocxBytes(docx_bytes);
const pdf_bytes = try doc.sourceBytes(a);
try std.fs.cwd().writeFile(.{ .sub_path = "document.pdf", .data = pdf_bytes });

Objective-C

NSData *docxBytes = [NSData dataWithContentsOfFile:@"document.docx"];
POXDocument *doc = [POXDocument openFromDocxBytes:docxBytes error:&err];
NSData *pdfBytes = [doc sourceBytesWithError:&err];
[pdfBytes writeToFile:@"document.pdf" atomically:YES];

Elixir

docx_bytes = File.read!("document.docx")
{:ok, doc} = PdfOxide.open_from_docx_bytes(docx_bytes)
{:ok, pdf_bytes} = PdfOxide.source_bytes(doc)
File.write!("document.pdf", pdf_bytes)

Підтримувані можливості DOCX

  • Абзаци з вирівнюванням (ліворуч, по центру, праворуч, за шириною)
  • Заголовки (стилі Заголовок 1–9)
  • Форматування тексту: жирний, курсив, підкреслення, закреслення
  • Розміри та кольори шрифтів
  • Нумеровані та марковані списки з вкладенням
  • Витягання метаданих (заголовок і автор з docProps/core.xml)

Таблиці Excel (XLSX)

Конвертуйте таблиці у PDF з автоматичним розрахунком ширини стовпців і підтримкою кількох аркушів. Кожен аркуш відображається як окремий розділ.

Python

from pdf_oxide import OfficeConverter

pdf = OfficeConverter.from_xlsx("data.xlsx")
pdf.save("data.pdf")

Rust

let converter = OfficeConverter::new();
let pdf_bytes = converter.convert_xlsx("data.xlsx")?;
std::fs::write("data.pdf", pdf_bytes)?;

C++

std::ifstream in("data.xlsx", std::ios::binary);
std::vector<std::uint8_t> xlsx((std::istreambuf_iterator<char>(in)), {});

auto doc = pdf_oxide::Document::open_from_xlsx_bytes(xlsx);
auto pdf = doc.get_source_bytes();
std::ofstream("data.pdf", std::ios::binary)
    .write(reinterpret_cast<const char*>(pdf.data()), pdf.size());

Dart

final xlsx = File('data.xlsx').readAsBytesSync();
final doc = PdfDocument.openFromXlsxBytes(xlsx);
File('data.pdf').writeAsBytesSync(doc.getSourceBytes());

R

xlsx <- readBin("data.xlsx", "raw", file.info("data.xlsx")$size)
doc  <- pdf_open_from_xlsx_bytes(xlsx)
writeBin(pdf_get_source_bytes(doc), "data.pdf")

Julia

xlsx = read("data.xlsx")
doc  = open_from_xlsx_bytes(xlsx)
write("data.pdf", get_source_bytes(doc))

Zig

const xlsx = try std.fs.cwd().readFileAlloc("data.xlsx", a, .unlimited);
var doc = try pdf_oxide.Document.openFromXlsxBytes(xlsx);
const pdf = try doc.sourceBytes(a);
try std.fs.cwd().writeFile(.{ .sub_path = "data.pdf", .data = pdf });

Objective-C

NSData *xlsx = [NSData dataWithContentsOfFile:@"data.xlsx"];
POXDocument *doc = [POXDocument openFromXlsxBytes:xlsx error:&err];
NSData *pdf = [doc sourceBytesWithError:&err];
[pdf writeToFile:@"data.pdf" atomically:YES];

Elixir

xlsx = File.read!("data.xlsx")
{:ok, doc} = PdfOxide.open_from_xlsx_bytes(xlsx)
{:ok, pdf} = PdfOxide.source_bytes(doc)
File.write!("data.pdf", pdf)

Підтримувані можливості XLSX

  • Відображення кількох аркушів із заголовками
  • Типи комірок: рядки, цілі числа, числа з плаваючою крапкою, булеві значення, дати, помилки
  • Автоматичний розрахунок ширини стовпців
  • Автоматичні розриви сторінок при перевищенні доступного простору

Презентації PowerPoint (PPTX)

Конвертуйте презентації у PDF. Кожен слайд стає сторінкою з витягнутими заголовками та текстовими блоками.

Python

from pdf_oxide import OfficeConverter

pdf = OfficeConverter.from_pptx("slides.pptx")
pdf.save("slides.pdf")

Rust

let converter = OfficeConverter::new();
let pdf_bytes = converter.convert_pptx("slides.pptx")?;
std::fs::write("slides.pdf", pdf_bytes)?;

C++

std::ifstream in("slides.pptx", std::ios::binary);
std::vector<std::uint8_t> pptx((std::istreambuf_iterator<char>(in)), {});

auto doc = pdf_oxide::Document::open_from_pptx_bytes(pptx);
auto pdf = doc.get_source_bytes();
std::ofstream("slides.pdf", std::ios::binary)
    .write(reinterpret_cast<const char*>(pdf.data()), pdf.size());

Dart

final pptx = File('slides.pptx').readAsBytesSync();
final doc = PdfDocument.openFromPptxBytes(pptx);
File('slides.pdf').writeAsBytesSync(doc.getSourceBytes());

R

pptx <- readBin("slides.pptx", "raw", file.info("slides.pptx")$size)
doc  <- pdf_open_from_pptx_bytes(pptx)
writeBin(pdf_get_source_bytes(doc), "slides.pdf")

Julia

pptx = read("slides.pptx")
doc  = open_from_pptx_bytes(pptx)
write("slides.pdf", get_source_bytes(doc))

Zig

const pptx = try std.fs.cwd().readFileAlloc("slides.pptx", a, .unlimited);
var doc = try pdf_oxide.Document.openFromPptxBytes(pptx);
const pdf = try doc.sourceBytes(a);
try std.fs.cwd().writeFile(.{ .sub_path = "slides.pdf", .data = pdf });

Objective-C

NSData *pptx = [NSData dataWithContentsOfFile:@"slides.pptx"];
POXDocument *doc = [POXDocument openFromPptxBytes:pptx error:&err];
NSData *pdf = [doc sourceBytesWithError:&err];
[pdf writeToFile:@"slides.pdf" atomically:YES];

Elixir

pptx = File.read!("slides.pptx")
{:ok, doc} = PdfOxide.open_from_pptx_bytes(pptx)
{:ok, pdf} = PdfOxide.source_bytes(doc)
File.write!("slides.pdf", pdf)

Як перетворити PDF на DOCX, PPTX або XLSX?

Зворотний напрямок — PDF → Office — реалізований як методи на відкритому PDF-документі, а не на OfficeConverter. Відкрийте PDF через PdfDocument (Python/Rust), OpenFromBytes/Open (Go/C#) або Document.open (Swift), а потім викличте to_docx / to_pptx / to_xlsx для експорту.

PDF Oxide автоматично обирає стратегію виводу залежно від кількості сторінок: документи в межах порогу компонування (30 сторінок для DOCX/PPTX, 200 для XLSX) використовують зберігаючий компонування шлях, що розміщує кожен текстовий фрагмент біля його вихідної позиції як позиційований редагований елемент; більші документи переходять на потоковий шлях, що перекомпоновує вміст, щоб Word/PowerPoint/Excel відкривали їх миттєво. Кожна сторінка PDF стає розділом DOCX, слайдом PPTX або аркушем XLSX; вихідні розміри сторінок та вбудовані шрифти зберігаються, тому при конвертації PDF → Office → PDF макет залишається початковим.

PDF у Word (DOCX)

Rust

use pdf_oxide::document::PdfDocument;

let doc = PdfDocument::open("report.pdf")?;

// Write straight to disk
doc.to_docx("report.docx")?;

// Or get the bytes in memory
let docx_bytes: Vec<u8> = doc.to_docx_bytes()?;
std::fs::write("report.docx", docx_bytes)?;

Python

from pdf_oxide import PdfDocument

doc = PdfDocument("report.pdf")

# Write straight to disk
doc.to_docx("report.docx")

# Or get the bytes in memory
docx_bytes = doc.to_docx_bytes()
with open("report.docx", "wb") as f:
    f.write(docx_bytes)

Go

doc, err := pdfoxide.Open("report.pdf")
if err != nil {
    log.Fatal(err)
}
defer doc.Close()

docxBytes, err := doc.ToDocxBytes()
if err != nil {
    log.Fatal(err)
}
os.WriteFile("report.docx", docxBytes, 0o644)

C#

using PdfOxide.Core;

using var doc = PdfDocument.Open("report.pdf");
byte[] docxBytes = doc.ToDocxBytes();
File.WriteAllBytes("report.docx", docxBytes);

Swift

import PdfOxide

let doc = try Document.open("report.pdf")
let docxBytes = try doc.toDocx()
try Data(docxBytes).write(to: URL(fileURLWithPath: "report.docx"))

C++

#include <pdf_oxide/pdf_oxide.hpp>
#include <fstream>

auto doc = pdf_oxide::Document::open("report.pdf");
auto docx_bytes = doc.to_docx();
std::ofstream("report.docx", std::ios::binary)
    .write(reinterpret_cast<const char*>(docx_bytes.data()), docx_bytes.size());

Dart

import 'dart:io';
import 'package:pdf_oxide/pdf_oxide.dart';

final doc = PdfDocument.open('report.pdf');
File('report.docx').writeAsBytesSync(doc.toDocx());

R

library(pdfoxide)

doc <- pdf_open("report.pdf")
writeBin(pdf_to_docx(doc), "report.docx")

Julia

using PdfOxide

doc = open_document("report.pdf")
write("report.docx", to_docx(doc))

Zig

const pdf_oxide = @import("pdf_oxide");
const a = std.heap.page_allocator;

var doc = try pdf_oxide.Document.open("report.pdf");
const docx_bytes = try doc.toDocx(a);
try std.fs.cwd().writeFile(.{ .sub_path = "report.docx", .data = docx_bytes });

Objective-C

#import "POXPdfOxide.h"
NSError *err = nil;

POXDocument *doc = [POXDocument openPath:@"report.pdf" error:&err];
NSData *docxBytes = [doc toDocxWithError:&err];
[docxBytes writeToFile:@"report.docx" atomically:YES];

Elixir

{:ok, doc} = PdfOxide.open("report.pdf")
{:ok, docx_bytes} = PdfOxide.to_docx(doc)
File.write!("report.docx", docx_bytes)

PDF у PowerPoint (PPTX)

Rust

use pdf_oxide::document::PdfDocument;

let doc = PdfDocument::open("deck.pdf")?;
doc.to_pptx("deck.pptx")?;            // to disk
let pptx_bytes = doc.to_pptx_bytes()?; // or in memory

Python

from pdf_oxide import PdfDocument

doc = PdfDocument("deck.pdf")
doc.to_pptx("deck.pptx")           # to disk
pptx_bytes = doc.to_pptx_bytes()   # or in memory

Go

doc, _ := pdfoxide.Open("deck.pdf")
defer doc.Close()
pptxBytes, err := doc.ToPptxBytes()
if err != nil {
    log.Fatal(err)
}
os.WriteFile("deck.pptx", pptxBytes, 0o644)

C#

using var doc = PdfDocument.Open("deck.pdf");
File.WriteAllBytes("deck.pptx", doc.ToPptxBytes());

Swift

let doc = try Document.open("deck.pdf")
let pptxBytes = try doc.toPptx()
try Data(pptxBytes).write(to: URL(fileURLWithPath: "deck.pptx"))

C++

auto doc = pdf_oxide::Document::open("deck.pdf");
auto pptx_bytes = doc.to_pptx();
std::ofstream("deck.pptx", std::ios::binary)
    .write(reinterpret_cast<const char*>(pptx_bytes.data()), pptx_bytes.size());

Dart

final doc = PdfDocument.open('deck.pdf');
File('deck.pptx').writeAsBytesSync(doc.toPptx());

R

doc <- pdf_open("deck.pdf")
writeBin(pdf_to_pptx(doc), "deck.pptx")

Julia

doc = open_document("deck.pdf")
write("deck.pptx", to_pptx(doc))

Zig

var doc = try pdf_oxide.Document.open("deck.pdf");
const pptx_bytes = try doc.toPptx(a);
try std.fs.cwd().writeFile(.{ .sub_path = "deck.pptx", .data = pptx_bytes });

Objective-C

POXDocument *doc = [POXDocument openPath:@"deck.pdf" error:&err];
NSData *pptxBytes = [doc toPptxWithError:&err];
[pptxBytes writeToFile:@"deck.pptx" atomically:YES];

Elixir

{:ok, doc} = PdfOxide.open("deck.pdf")
{:ok, pptx_bytes} = PdfOxide.to_pptx(doc)
File.write!("deck.pptx", pptx_bytes)

PDF у Excel (XLSX)

Rust

use pdf_oxide::document::PdfDocument;

let doc = PdfDocument::open("table.pdf")?;
doc.to_xlsx("table.xlsx")?;            // to disk
let xlsx_bytes = doc.to_xlsx_bytes()?; // or in memory

Python

from pdf_oxide import PdfDocument

doc = PdfDocument("table.pdf")
doc.to_xlsx("table.xlsx")          # to disk
xlsx_bytes = doc.to_xlsx_bytes()   # or in memory

Go

doc, _ := pdfoxide.Open("table.pdf")
defer doc.Close()
xlsxBytes, err := doc.ToXlsxBytes()
if err != nil {
    log.Fatal(err)
}
os.WriteFile("table.xlsx", xlsxBytes, 0o644)

C#

using var doc = PdfDocument.Open("table.pdf");
File.WriteAllBytes("table.xlsx", doc.ToXlsxBytes());

Swift

let doc = try Document.open("table.pdf")
let xlsxBytes = try doc.toXlsx()
try Data(xlsxBytes).write(to: URL(fileURLWithPath: "table.xlsx"))

C++

auto doc = pdf_oxide::Document::open("table.pdf");
auto xlsx_bytes = doc.to_xlsx();
std::ofstream("table.xlsx", std::ios::binary)
    .write(reinterpret_cast<const char*>(xlsx_bytes.data()), xlsx_bytes.size());

Dart

final doc = PdfDocument.open('table.pdf');
File('table.xlsx').writeAsBytesSync(doc.toXlsx());

R

doc <- pdf_open("table.pdf")
writeBin(pdf_to_xlsx(doc), "table.xlsx")

Julia

doc = open_document("table.pdf")
write("table.xlsx", to_xlsx(doc))

Zig

var doc = try pdf_oxide.Document.open("table.pdf");
const xlsx_bytes = try doc.toXlsx(a);
try std.fs.cwd().writeFile(.{ .sub_path = "table.xlsx", .data = xlsx_bytes });

Objective-C

POXDocument *doc = [POXDocument openPath:@"table.pdf" error:&err];
NSData *xlsxBytes = [doc toXlsxWithError:&err];
[xlsxBytes writeToFile:@"table.xlsx" atomically:YES];

Elixir

{:ok, doc} = PdfOxide.open("table.pdf")
{:ok, xlsx_bytes} = PdfOxide.to_xlsx(doc)
File.write!("table.xlsx", xlsx_bytes)

Примітка для Python: to_docx/to_pptx/to_xlsx визначені на PdfDocument (клас для вилучення тексту та інспекції), а не на OfficeConverter/Pdf (будівник для напрямку Office → PDF). Використовуйте PdfDocument("file.pdf") для відкриття вихідного PDF.


Як відкрити файл Office безпосередньо як PDF-документ?

Нативні прив’язки (Go, C#, Swift і C ABI) надають конструктори open_from_*_bytes, що конвертують байти DOCX/PPTX/XLSX і повертають вже відкритий PdfDocument — зручно, коли потрібно одразу вилучати текст, рендерити або реекспортувати без збереження проміжного PDF. Кожен конструктор внутрішньо запускає OfficeConverter і відкриває отриманий PDF за один виклик.

Go

data, err := os.ReadFile("contract.docx")
if err != nil {
    log.Fatal(err)
}

doc, err := pdfoxide.OpenFromDocxBytes(data)
if err != nil {
    log.Fatal(err)
}
defer doc.Close()

// Now work with it as a normal PDF document
text, _ := doc.ExtractText(0)
fmt.Println(text)

C#

using PdfOxide.Core;

byte[] data = File.ReadAllBytes("contract.docx");
using var doc = PdfDocument.OpenFromDocxBytes(data);

// Use it like any other open PDF — extract, render, or re-export
byte[] pdfBytes = doc.ToDocxBytes(); // round-trip if you like

Swift

import PdfOxide
import Foundation

let data = try Data(contentsOf: URL(fileURLWithPath: "contract.docx"))
let doc = try Document.openFromDocxBytes([UInt8](data))
let pageCount = try doc.pageCount()
print("Converted DOCX has \(pageCount) page(s)")

C++

#include <pdf_oxide/pdf_oxide.hpp>
#include <fstream>

std::ifstream in("contract.docx", std::ios::binary);
std::vector<std::uint8_t> data((std::istreambuf_iterator<char>(in)), {});

auto doc = pdf_oxide::Document::open_from_docx_bytes(data);
// Now work with it as a normal PDF document
auto text = doc.extract_text(0);

Dart

import 'dart:io';
import 'package:pdf_oxide/pdf_oxide.dart';

final data = File('contract.docx').readAsBytesSync();
final doc = PdfDocument.openFromDocxBytes(data);
final text = doc.extractText(0);

R

library(pdfoxide)

data <- readBin("contract.docx", "raw", file.info("contract.docx")$size)
doc  <- pdf_open_from_docx_bytes(data)
text <- pdf_extract_text(doc, 0)

Julia

using PdfOxide

data = read("contract.docx")
doc  = open_from_docx_bytes(data)
text = extract_text(doc, 0)

Zig

const pdf_oxide = @import("pdf_oxide");
const a = std.heap.page_allocator;

const data = try std.fs.cwd().readFileAlloc("contract.docx", a, .unlimited);
var doc = try pdf_oxide.Document.openFromDocxBytes(data);
const text = try doc.extractText(a, 0);

Objective-C

#import "POXPdfOxide.h"
NSError *err = nil;

NSData *data = [NSData dataWithContentsOfFile:@"contract.docx"];
POXDocument *doc = [POXDocument openFromDocxBytes:data error:&err];
NSString *text = [doc extractText:0 error:&err];

Elixir

data = File.read!("contract.docx")
{:ok, doc} = PdfOxide.open_from_docx_bytes(data)
{:ok, text} = PdfOxide.extract_text(doc, 0)

Для PPTX і XLSX використовуються відповідні конструктори:

Вихідний формат Go C# Swift
DOCX OpenFromDocxBytes(data) PdfDocument.OpenFromDocxBytes(data) Document.openFromDocxBytes(bytes)
PPTX OpenFromPptxBytes(data) PdfDocument.OpenFromPptxBytes(data) Document.openFromPptxBytes(bytes)
XLSX OpenFromXlsxBytes(data) PdfDocument.OpenFromXlsxBytes(data) Document.openFromXlsxBytes(bytes)

Rust / Python: у ядрі PdfDocument немає конструктора open_from_docx_bytes. У Rust спочатку виконайте конвертацію через OfficeConverter::new().convert_docx_bytes(&data)?, а потім відкрийте документ через PdfDocument::from_bytes(pdf_bytes)?. У Python використовуйте OfficeConverter.from_docx_bytes(data) (описано вище); він повертає Pdf.

use pdf_oxide::converters::office::OfficeConverter;
use pdf_oxide::document::PdfDocument;

let data = std::fs::read("contract.docx")?;
let pdf_bytes = OfficeConverter::new().convert_docx_bytes(&data)?;
let doc = PdfDocument::from_bytes(pdf_bytes)?;
println!("{} pages", doc.page_count()?);

Налаштування (Rust)

Налаштуйте розмір сторінки, поля та шрифти за допомогою OfficeConfig:

use pdf_oxide::converters::office::{OfficeConverter, OfficeConfig};

let config = OfficeConfig::a4(); // A4 page size
let converter = OfficeConverter::with_config(config);
let pdf_bytes = converter.convert_docx("document.docx")?;

Поля OfficeConfig

Поле Тип За замовчуванням Опис
page_size PageSize Letter Розміри сторінки
margins Margins По 1 дюйму з усіх сторін Поля сторінки в пунктах (72pt = 1 дюйм)
embed_fonts bool false Чи вбудовувати шрифти
default_font String "Helvetica" Резервний шрифт
default_font_size f32 11.0 Розмір тексту за замовчуванням у пунктах
line_height f32 1.2 Множник міжрядкового інтервалу
include_images bool true Чи включати вбудовані зображення

Попередньо встановлені розміри сторінок

let config = OfficeConfig::letter(); // 8.5 × 11 inches (default)
let config = OfficeConfig::a4();     // 210 × 297 mm

Довільні поля

use pdf_oxide::converters::office::Margins;

let mut config = OfficeConfig::letter();
config.margins = Margins::uniform(36.0);  // 0.5 inch margins
config.margins = Margins::none();          // No margins

Пакетна конвертація

Python

from pdf_oxide import OfficeConverter
from pathlib import Path

office_dir = Path("documents/")
output_dir = Path("pdfs/")
output_dir.mkdir(exist_ok=True)

extensions = {".docx", ".xlsx", ".pptx"}

for doc_path in office_dir.iterdir():
    if doc_path.suffix.lower() in extensions:
        pdf = OfficeConverter.convert(str(doc_path))
        pdf.save(str(output_dir / doc_path.with_suffix(".pdf").name))
        print(f"Converted: {doc_path.name}")

Rust

use pdf_oxide::converters::office::OfficeConverter;
use std::fs;

let converter = OfficeConverter::new();

for entry in fs::read_dir("documents/")? {
    let path = entry?.path();
    match path.extension().and_then(|e| e.to_str()) {
        Some("docx" | "xlsx" | "pptx") => {
            let pdf_bytes = converter.convert(&path)?;
            let out = format!("pdfs/{}.pdf", path.file_stem().unwrap().to_str().unwrap());
            fs::write(&out, pdf_bytes)?;
            println!("Converted: {}", path.display());
        }
        _ => {}
    }
}

C++

#include <pdf_oxide/pdf_oxide.hpp>
#include <filesystem>
#include <fstream>
namespace fs = std::filesystem;

for (const auto& entry : fs::directory_iterator("documents/")) {
    auto path = entry.path();
    auto ext = path.extension().string();

    if (ext != ".docx" && ext != ".xlsx" && ext != ".pptx") continue;

    std::ifstream in(path, std::ios::binary);
    std::vector<std::uint8_t> bytes((std::istreambuf_iterator<char>(in)), {});

    auto doc =
        ext == ".docx" ? pdf_oxide::Document::open_from_docx_bytes(bytes)
        : ext == ".xlsx" ? pdf_oxide::Document::open_from_xlsx_bytes(bytes)
                         : pdf_oxide::Document::open_from_pptx_bytes(bytes);

    auto pdf = doc.get_source_bytes();
    auto out = "pdfs/" + path.stem().string() + ".pdf";
    std::ofstream(out, std::ios::binary)
        .write(reinterpret_cast<const char*>(pdf.data()), pdf.size());
}

Dart

import 'dart:io';
import 'package:pdf_oxide/pdf_oxide.dart';

Directory('pdfs').createSync(recursive: true);

for (final entry in Directory('documents').listSync()) {
  if (entry is! File) continue;
  final ext = entry.path.split('.').last.toLowerCase();
  final bytes = entry.readAsBytesSync();

  final doc = switch (ext) {
    'docx' => PdfDocument.openFromDocxBytes(bytes),
    'xlsx' => PdfDocument.openFromXlsxBytes(bytes),
    'pptx' => PdfDocument.openFromPptxBytes(bytes),
    _ => null,
  };
  if (doc == null) continue;

  final name = entry.uri.pathSegments.last.replaceAll(RegExp(r'\.\w+$'), '');
  File('pdfs/$name.pdf').writeAsBytesSync(doc.getSourceBytes());
}

R

library(pdfoxide)

dir.create("pdfs", showWarnings = FALSE)

for (path in list.files("documents", full.names = TRUE)) {
  ext   <- tolower(tools::file_ext(path))
  bytes <- readBin(path, "raw", file.info(path)$size)

  doc <- switch(ext,
    docx = pdf_open_from_docx_bytes(bytes),
    xlsx = pdf_open_from_xlsx_bytes(bytes),
    pptx = pdf_open_from_pptx_bytes(bytes),
    next)

  out <- file.path("pdfs", paste0(tools::file_path_sans_ext(basename(path)), ".pdf"))
  writeBin(pdf_get_source_bytes(doc), out)
}

Julia

using PdfOxide

mkpath("pdfs")

for path in readdir("documents"; join = true)
    ext   = lowercase(splitext(path)[2])
    bytes = read(path)

    doc = if ext == ".docx"
        open_from_docx_bytes(bytes)
    elseif ext == ".xlsx"
        open_from_xlsx_bytes(bytes)
    elseif ext == ".pptx"
        open_from_pptx_bytes(bytes)
    else
        continue
    end

    name = first(splitext(basename(path)))
    write(joinpath("pdfs", name * ".pdf"), get_source_bytes(doc))
end

Zig

const pdf_oxide = @import("pdf_oxide");
const a = std.heap.page_allocator;

try std.fs.cwd().makePath("pdfs");
var dir = try std.fs.cwd().openDir("documents", .{ .iterate = true });
var it = dir.iterate();
while (try it.next()) |entry| {
    const bytes = try dir.readFileAlloc(entry.name, a, .unlimited);

    var doc = if (std.mem.endsWith(u8, entry.name, ".docx"))
        try pdf_oxide.Document.openFromDocxBytes(bytes)
    else if (std.mem.endsWith(u8, entry.name, ".xlsx"))
        try pdf_oxide.Document.openFromXlsxBytes(bytes)
    else if (std.mem.endsWith(u8, entry.name, ".pptx"))
        try pdf_oxide.Document.openFromPptxBytes(bytes)
    else
        continue;

    const pdf = try doc.sourceBytes(a);
    const stem = entry.name[0 .. std.mem.lastIndexOfScalar(u8, entry.name, '.').?];
    const out = try std.fmt.allocPrint(a, "pdfs/{s}.pdf", .{stem});
    try std.fs.cwd().writeFile(.{ .sub_path = out, .data = pdf });
}

Objective-C

#import "POXPdfOxide.h"
NSError *err = nil;
NSFileManager *fm = [NSFileManager defaultManager];
[fm createDirectoryAtPath:@"pdfs" withIntermediateDirectories:YES attributes:nil error:&err];

for (NSString *name in [fm contentsOfDirectoryAtPath:@"documents" error:&err]) {
    NSString *path = [@"documents" stringByAppendingPathComponent:name];
    NSData *bytes = [NSData dataWithContentsOfFile:path];
    NSString *ext = name.pathExtension.lowercaseString;

    POXDocument *doc;
    if ([ext isEqualToString:@"docx"])      doc = [POXDocument openFromDocxBytes:bytes error:&err];
    else if ([ext isEqualToString:@"xlsx"]) doc = [POXDocument openFromXlsxBytes:bytes error:&err];
    else if ([ext isEqualToString:@"pptx"]) doc = [POXDocument openFromPptxBytes:bytes error:&err];
    else continue;

    NSData *pdf = [doc sourceBytesWithError:&err];
    NSString *out = [@"pdfs" stringByAppendingPathComponent:
        [name.stringByDeletingPathExtension stringByAppendingPathExtension:@"pdf"]];
    [pdf writeToFile:out atomically:YES];
}

Elixir

File.mkdir_p!("pdfs")

for name <- File.ls!("documents") do
  bytes = File.read!(Path.join("documents", name))

  result =
    case Path.extname(name) |> String.downcase() do
      ".docx" -> PdfOxide.open_from_docx_bytes(bytes)
      ".xlsx" -> PdfOxide.open_from_xlsx_bytes(bytes)
      ".pptx" -> PdfOxide.open_from_pptx_bytes(bytes)
      _ -> :skip
    end

  with {:ok, doc} <- result,
       {:ok, pdf} <- PdfOxide.source_bytes(doc) do
    out = Path.join("pdfs", Path.rootname(name) <> ".pdf")
    File.write!(out, pdf)
  end
end

Довідник з API

<a id=“office-pdf-officeconverter”></a>

Python — OfficeConverter

Метод Повертає Опис
OfficeConverter.convert(path) Pdf Автоматично визначити формат і конвертувати
OfficeConverter.from_docx(path) Pdf Конвертувати файл DOCX
OfficeConverter.from_docx_bytes(data) Pdf Конвертувати DOCX з байтів
OfficeConverter.from_xlsx(path) Pdf Конвертувати файл XLSX
OfficeConverter.from_xlsx_bytes(data) Pdf Конвертувати XLSX з байтів
OfficeConverter.from_pptx(path) Pdf Конвертувати файл PPTX
OfficeConverter.from_pptx_bytes(data) Pdf Конвертувати PPTX з байтів

Усі методи повертають об’єкт Pdf. Викличте pdf.save("output.pdf") або pdf.to_bytes() для отримання результату.

Rust — OfficeConverter

Метод Повертає Опис
OfficeConverter::new() OfficeConverter Створити з налаштуваннями за замовчуванням
OfficeConverter::with_config(config) OfficeConverter Створити з користувацькою конфігурацією
convert(path) Result<Vec<u8>> Автоматично визначити формат і конвертувати
convert_docx(path) Result<Vec<u8>> Конвертувати файл DOCX
convert_docx_bytes(bytes) Result<Vec<u8>> Конвертувати DOCX з байтів
convert_xlsx(path) Result<Vec<u8>> Конвертувати файл XLSX
convert_xlsx_bytes(bytes) Result<Vec<u8>> Конвертувати XLSX з байтів
convert_pptx(path) Result<Vec<u8>> Конвертувати файл PPTX
convert_pptx_bytes(bytes) Result<Vec<u8>> Конвертувати PPTX з байтів

PDF → Office — to_docx / to_pptx / to_xlsx

Експорт з відкритого PDF-документа. Доступний у Rust, Python, Go, C# і Swift.

Мова Метод Повертає Опис
Rust PdfDocument::to_docx(path) Result<()> Експортувати PDF у файл DOCX на диску
Rust PdfDocument::to_docx_bytes() Result<Vec<u8>> Експортувати PDF у байти DOCX
Rust PdfDocument::to_pptx(path) / to_pptx_bytes() Result<()> / Result<Vec<u8>> Експортувати PDF у PPTX
Rust PdfDocument::to_xlsx(path) / to_xlsx_bytes() Result<()> / Result<Vec<u8>> Експортувати PDF у XLSX
Python PdfDocument.to_docx(path) / to_docx_bytes() None / bytes Експортувати PDF у DOCX
Python PdfDocument.to_pptx(path) / to_pptx_bytes() None / bytes Експортувати PDF у PPTX
Python PdfDocument.to_xlsx(path) / to_xlsx_bytes() None / bytes Експортувати PDF у XLSX
Go (*PdfDocument).ToDocxBytes() ([]byte, error) Експортувати PDF у байти DOCX
Go (*PdfDocument).ToPptxBytes() ([]byte, error) Експортувати PDF у байти PPTX
Go (*PdfDocument).ToXlsxBytes() ([]byte, error) Експортувати PDF у байти XLSX
C# PdfDocument.ToDocxBytes() byte[] Експортувати PDF у байти DOCX
C# PdfDocument.ToPptxBytes() byte[] Експортувати PDF у байти PPTX
C# PdfDocument.ToXlsxBytes() byte[] Експортувати PDF у байти XLSX
Swift Document.toDocx() [UInt8] Експортувати PDF у байти DOCX
Swift Document.toPptx() [UInt8] Експортувати PDF у байти PPTX
Swift Document.toXlsx() [UInt8] Експортувати PDF у байти XLSX

Office → PDF-документ — open_from_*_bytes

Зручні конструктори нативних прив’язок, що конвертують байти Office і повертають відкритий PDF-документ. Доступні в Go, C#, Swift і C ABI. Недоступні в ядрі Rust PdfDocument і Python — використовуйте там OfficeConverter (дивіться таблицю вище).

Мова Конструктор Повертає Опис
Go OpenFromDocxBytes(data) (*PdfDocument, error) Відкрити PDF-документ з байтів DOCX
Go OpenFromPptxBytes(data) (*PdfDocument, error) Відкрити PDF-документ з байтів PPTX
Go OpenFromXlsxBytes(data) (*PdfDocument, error) Відкрити PDF-документ з байтів XLSX
C# PdfDocument.OpenFromDocxBytes(data) PdfDocument Відкрити PDF-документ з байтів DOCX
C# PdfDocument.OpenFromPptxBytes(data) PdfDocument Відкрити PDF-документ з байтів PPTX
C# PdfDocument.OpenFromXlsxBytes(data) PdfDocument Відкрити PDF-документ з байтів XLSX
Swift Document.openFromDocxBytes(bytes) Document Відкрити PDF-документ з байтів DOCX
Swift Document.openFromPptxBytes(bytes) Document Відкрити PDF-документ з байтів PPTX
Swift Document.openFromXlsxBytes(bytes) Document Відкрити PDF-документ з байтів XLSX
C ABI pdf_document_open_from_docx_bytes(data, len, error_code) PdfDocument * Відкрити PDF-документ з байтів DOCX
C ABI pdf_document_open_from_pptx_bytes(data, len, error_code) PdfDocument * Відкрити PDF-документ з байтів PPTX
C ABI pdf_document_open_from_xlsx_bytes(data, len, error_code) PdfDocument * Відкрити PDF-документ з байтів XLSX

Часті запитання

Чи зберігається макет при конвертації PDF у DOCX?

Так, у певних межах. Для документів у межах порогу компонування (30 сторінок для DOCX/PPTX, 200 для XLSX) to_docx_bytes / to_pptx_bytes / to_xlsx_bytes використовують зберігаючий компонування шлях, що виводить кожен текстовий фрагмент PDF як позиційований редагований елемент і вбудовує шрифти вихідного PDF, завдяки чому при конвертації PDF → Office → PDF початкові розміри сторінок зберігаються. Більші документи переходять на потоковий шлях, що перекомпоновує текст у справжні абзаци, щоб Word/PowerPoint/Excel відкривали їх миттєво.

Чи можна конвертувати PDF не лише у Word, а й у PowerPoint або Excel?

Так. to_pptx/to_pptx_bytes відображають кожну сторінку PDF як один слайд з розмірами, що відповідають MediaBox джерела, а to_xlsx/to_xlsx_bytes — як один аркуш. Обидва доступні у Rust, Python, Go, C# і Swift.

Чому в Python немає конструктора open_from_docx_bytes?

Python надає напрямок Office → PDF через вищорівневий клас OfficeConverter (OfficeConverter.from_docx_bytes(data) повертає Pdf). Конструктори open_from_*_bytes — це зручні обгортки, додані на рівні нативного FFI (Go, C#, Swift, C ABI), де немає окремого класу-конвертора.

Чи потрібно встановлювати Microsoft Office або LibreOffice?

Ні. PDF Oxide читає і записує формат OOXML (DOCX/XLSX/PPTX) безпосередньо — у чистому Rust. Жодних зовнішніх викликів процесів, COM-автоматизації чи безголових екземплярів Office — конвертація однаково працює на Linux, macOS і Windows.


Пов’язані сторінки