Skip to content

편집 개요

PDF Oxide는 기존 PDF를 편집하기 위해 두 가지 수준의 API를 제공합니다. 권장되는 고수준 Pdf 클래스와 저수준 DocumentEditor입니다. 두 가지 모두 PDF를 열고, 콘텐츠와 메타데이터를 수정하고, 변경 사항을 추적하고 결과를 저장할 수 있습니다.

편집 기능의 바인딩 지원 현황. 가장 풍부한 편집 기능을 제공하는 것은 Python, Rust, WASM으로, 페이지 작업, 텍스트/이미지 편집, 주석 처리, 암호화, 묵선 처리를 지원합니다. Go는 풍부한 편집기 API(메타데이터, 페이지 회전/이동/삭제, 영역 지우기, 양식 채우기/평탄화, 자르기, 병합, 암호화 저장)를 제공합니다. **C#**은 현재 메타데이터 편집(Title/Author/Subject), 양식 채우기(SetFormFieldValue), FlattenForms, 그리고 DocumentEditorSave/SaveAsync를 지원합니다. 페이지 수준 작업, 암호화, 묵선 처리, 텍스트/이미지 편집은 아직 C# 공개 API에 노출되지 않았으므로 이러한 기능에는 CLI, Go, Python 또는 Rust 바인딩을 사용하세요.

편집을 위해 PDF 열기

Python

from pdf_oxide import PdfDocument

doc = PdfDocument("input.pdf")

편집기는 첫 번째 수정 시 지연 초기화됩니다. 즉시 읽기를 시작할 수 있으며, set_title()이나 page() 같은 변경 메서드를 호출할 때 편집기가 활성화됩니다.

WASM

import { WasmPdfDocument } from "pdf-oxide-wasm";

const bytes = new Uint8Array(/* file bytes */);
const doc = new WasmPdfDocument(bytes);

Rust

통합 Pdf API 사용:

use pdf_oxide::api::Pdf;

let mut doc = Pdf::open("input.pdf")?;

또는 더 세밀한 제어가 필요할 때 DocumentEditor를 직접 사용:

use pdf_oxide::editor::DocumentEditor;

let mut editor = DocumentEditor::open("input.pdf")?;

Go

package main

import (
    "log"
    pdfoxide "github.com/yfedoseev/pdf_oxide/go"
)

func main() {
    editor, err := pdfoxide.OpenEditor("input.pdf")
    if err != nil { log.Fatal(err) }
    defer editor.Close()
}

C#

using PdfOxide;

using var editor = DocumentEditor.Open("input.pdf");

Java

import fyi.oxide.pdf.DocumentEditor;
import java.nio.file.Path;

try (DocumentEditor editor = DocumentEditor.open(Path.of("input.pdf"))) {
    // ...
}

Kotlin

import fyi.oxide.pdf.DocumentEditor
import java.nio.file.Path

DocumentEditor.open(Path.of("input.pdf")).use { editor ->
    // ...
}

Scala

import fyi.oxide.pdf.DocumentEditor
import scala.util.Using

Using.resource(DocumentEditor.open("input.pdf")) { editor =>
  // ...
}

Clojure

(require '[pdf-oxide.core :as pdf])

(with-open [editor (pdf/editor "input.pdf")]
  ;; ...
  )

Ruby

require 'pdf_oxide'

PdfOxide::DocumentEditor.open('input.pdf') do |editor|
  # ...
end

PHP

use PdfOxide\DocumentEditor;

$editor = DocumentEditor::open('input.pdf');

C++

#include <pdf_oxide/pdf_oxide.hpp>

auto editor = pdf_oxide::DocumentEditor::open("input.pdf");

Swift

import PdfOxide

let editor = try DocumentEditor.open("input.pdf")

Dart

import 'package:pdf_oxide/pdf_oxide.dart';

final editor = DocumentEditor.open('input.pdf');

R

library(pdfoxide)

editor <- pdf_editor_open("input.pdf")

Julia

using PdfOxide

editor = open_editor("input.pdf")

Zig

const pdf_oxide = @import("pdf_oxide");

var editor = try pdf_oxide.DocumentEditor.open("input.pdf");
defer editor.deinit();

Objective-C

#import "POXPdfOxide.h"

NSError *err = nil;
POXDocumentEditor *editor = [POXDocumentEditor openEditor:@"input.pdf" error:&err];

Elixir

{:ok, editor} = PdfOxide.open_editor("input.pdf")

수정 여부 확인

저장하기 전에 변경 사항이 있는지 확인할 수 있습니다:

Python

doc = PdfDocument("input.pdf")
print(doc.is_modified)  # False -- no changes yet

doc.set_title("Updated Title")
print(doc.is_modified)  # True

Rust

let mut doc = Pdf::open("input.pdf")?;
assert!(!doc.is_modified());

doc.editor().unwrap().set_title("Updated Title");
assert!(doc.is_modified());

Go

editor, _ := pdfoxide.OpenEditor("input.pdf")
defer editor.Close()

modified, _ := editor.IsModified()
fmt.Println(modified) // false

_ = editor.SetTitle("Updated Title")
modified, _ = editor.IsModified()
fmt.Println(modified) // true

C#

using var editor = DocumentEditor.Open("input.pdf");
Console.WriteLine(editor.IsModified); // false

editor.Title = "Updated Title";
Console.WriteLine(editor.IsModified); // true

PHP

$editor = DocumentEditor::open('input.pdf');
var_dump($editor->isModified()); // false

$editor->setProducer('pdf_oxide');
var_dump($editor->isModified()); // true

C++

auto editor = pdf_oxide::DocumentEditor::open("input.pdf");
bool before = editor.is_modified(); // false

editor.set_producer("pdf_oxide");
bool after = editor.is_modified(); // true

Swift

let editor = try DocumentEditor.open("input.pdf")
try editor.isModified() // false

try editor.setProducer("pdf_oxide")
try editor.isModified() // true

Dart

final editor = DocumentEditor.open('input.pdf');
editor.isModified(); // false

editor.setProducer('pdf_oxide');
editor.isModified(); // true

R

editor <- pdf_editor_open("input.pdf")
pdf_editor_is_modified(editor) # FALSE

pdf_editor_set_producer(editor, "pdf_oxide")
pdf_editor_is_modified(editor) # TRUE

Julia

editor = open_editor("input.pdf")
is_modified(editor) # false

set_producer(editor, "pdf_oxide")
is_modified(editor) # true

Zig

var editor = try pdf_oxide.DocumentEditor.open("input.pdf");
defer editor.deinit();
_ = editor.isModified(); // false

try editor.setProducer("pdf_oxide");
_ = editor.isModified(); // true

Objective-C

NSError *err = nil;
POXDocumentEditor *editor = [POXDocumentEditor openEditor:@"input.pdf" error:&err];
[editor isModified]; // NO

[editor setProducer:@"pdf_oxide" error:&err];
[editor isModified]; // YES

Elixir

{:ok, editor} = PdfOxide.open_editor("input.pdf")
PdfOxide.editor_modified?(editor) # false

PdfOxide.set_producer(editor, "pdf_oxide")
PdfOxide.editor_modified?(editor) # true

저장

Python

doc = PdfDocument("input.pdf")
doc.set_title("New Title")
doc.save("output.pdf")

WASM

import { WasmPdfDocument } from "pdf-oxide-wasm";

const bytes = new Uint8Array(/* file bytes */);
const doc = new WasmPdfDocument(bytes);
doc.setTitle("New Title");
const output = doc.save();
doc.free();

Rust

let mut doc = Pdf::open("input.pdf")?;
doc.editor().unwrap().set_title("New Title");
doc.save("output.pdf")?;

// Or save to a new path
doc.save_as("copy.pdf")?;

Go

editor, _ := pdfoxide.OpenEditor("input.pdf")
defer editor.Close()

_ = editor.SetTitle("New Title")
_ = editor.Save("output.pdf")

C#

using var editor = DocumentEditor.Open("input.pdf");
editor.Title = "New Title";
editor.Save("output.pdf");

PHP

$editor = DocumentEditor::open('input.pdf');
$editor->setProducer('pdf_oxide');
$editor->saveTo('output.pdf');

C++

auto editor = pdf_oxide::DocumentEditor::open("input.pdf");
editor.set_producer("pdf_oxide");
editor.save("output.pdf");

Swift

let editor = try DocumentEditor.open("input.pdf")
try editor.setProducer("pdf_oxide")
try editor.save("output.pdf")

Dart

final editor = DocumentEditor.open('input.pdf');
editor.setProducer('pdf_oxide');
editor.save('output.pdf');

R

editor <- pdf_editor_open("input.pdf")
pdf_editor_set_producer(editor, "pdf_oxide")
pdf_editor_save(editor, "output.pdf")

Julia

editor = open_editor("input.pdf")
set_producer(editor, "pdf_oxide")
save(editor, "output.pdf")

Zig

var editor = try pdf_oxide.DocumentEditor.open("input.pdf");
defer editor.deinit();
try editor.setProducer("pdf_oxide");
try editor.save("output.pdf");

Objective-C

NSError *err = nil;
POXDocumentEditor *editor = [POXDocumentEditor openEditor:@"input.pdf" error:&err];
[editor setProducer:@"pdf_oxide" error:&err];
[editor saveToPath:@"output.pdf" error:&err];

Elixir

{:ok, editor} = PdfOxide.open_editor("input.pdf")
PdfOxide.set_producer(editor, "pdf_oxide")
PdfOxide.editor_save(editor, "output.pdf")

save() 메서드는 기본적으로 PDF를 완전히 다시 씁니다. 고급 저장 옵션(증분 업데이트, 암호화)은 암호화 및 보안을 참조하세요.

문서 메타데이터

제목, 저자, 주제, 키워드 등 표준 PDF 메타데이터 필드를 읽고 씁니다.

Python

from pdf_oxide import PdfDocument

doc = PdfDocument("input.pdf")

# Set metadata
doc.set_title("Quarterly Report")
doc.set_author("Jane Smith")
doc.set_subject("Q4 2025 Financial Results")
doc.set_keywords("finance, quarterly, 2025")

doc.save("output.pdf")

WASM

import { WasmPdfDocument } from "pdf-oxide-wasm";

const bytes = new Uint8Array(/* file bytes */);
const doc = new WasmPdfDocument(bytes);

// Set metadata
doc.setTitle("Quarterly Report");
doc.setAuthor("Jane Smith");
doc.setSubject("Q4 2025 Financial Results");
doc.setKeywords("finance, quarterly, 2025");

const output = doc.save();
doc.free();

Rust

use pdf_oxide::editor::DocumentEditor;

let mut editor = DocumentEditor::open("input.pdf")?;

// Read metadata
if let Some(title) = editor.title()? {
    println!("Current title: {}", title);
}
if let Some(author) = editor.author()? {
    println!("Current author: {}", author);
}
if let Some(subject) = editor.subject()? {
    println!("Current subject: {}", subject);
}
if let Some(keywords) = editor.keywords()? {
    println!("Current keywords: {}", keywords);
}

// Set metadata
editor.set_title("Quarterly Report");
editor.set_author("Jane Smith");
editor.set_subject("Q4 2025 Financial Results");
editor.set_keywords("finance, quarterly, 2025");

editor.save("output.pdf")?;

Go

editor, _ := pdfoxide.OpenEditor("input.pdf")
defer editor.Close()

if t, err := editor.Title(); err == nil { fmt.Println("Current title:", t) }
if a, err := editor.Author(); err == nil { fmt.Println("Current author:", a) }

_ = editor.SetTitle("Quarterly Report")
_ = editor.SetAuthor("Jane Smith")
_ = editor.SetSubject("Q4 2025 Financial Results")

_ = editor.Save("output.pdf")

C#

using var editor = DocumentEditor.Open("input.pdf");

if (editor.Title is { } t) Console.WriteLine($"Current title: {t}");
if (editor.Author is { } a) Console.WriteLine($"Current author: {a}");
if (editor.Subject is { } s) Console.WriteLine($"Current subject: {s}");

editor.Title = "Quarterly Report";
editor.Author = "Jane Smith";
editor.Subject = "Q4 2025 Financial Results";

editor.Save("output.pdf");

문서 정보

소스 경로 및 버전

use pdf_oxide::editor::DocumentEditor;

let editor = DocumentEditor::open("input.pdf")?;

// Path to the original file
println!("Source: {}", editor.source_path());

// PDF version as (major, minor)
let (major, minor) = editor.version();
println!("PDF version: {}.{}", major, minor);

// Number of pages
println!("Pages: {}", editor.current_page_count());

전체 API 참조

DocumentEditor

메서드 반환값 설명
open(path) Result<DocumentEditor> 편집을 위해 PDF 열기
is_modified() bool 변경 사항이 있는지 확인
source_path() &str 소스 PDF 경로
source() &PdfDocument 소스 문서에 대한 읽기 전용 접근
version() (u8, u8) PDF 버전 (메이저, 마이너)
current_page_count() usize 문서의 페이지 수
title() Result<Option<String>> 문서 제목 가져오기
set_title(title) () 문서 제목 설정
author() Result<Option<String>> 문서 저자 가져오기
set_author(author) () 문서 저자 설정
subject() Result<Option<String>> 문서 주제 가져오기
set_subject(subject) () 문서 주제 설정
keywords() Result<Option<String>> 문서 키워드 가져오기
set_keywords(keywords) () 문서 키워드 설정
save(path) Result<()> 완전 재작성으로 저장
save_with_options(path, options) Result<()> 사용자 정의 옵션으로 저장

Pdf (통합 API)

메서드 반환값 설명
Pdf::open(path) Result<Pdf> 편집을 위해 PDF 열기
Pdf::open_editor(path) Result<DocumentEditor> DocumentEditor로 직접 열기
is_modified() bool 변경 사항 존재 여부 확인
save(path) Result<()> 문서 저장
save_as(path) Result<()> 새 경로에 저장
page(index) Result<PdfPage> DOM 편집을 위해 페이지 가져오기
save_page(page) Result<()> 수정된 페이지 다시 저장
editor() Option<&mut DocumentEditor> 내부 편집기 접근

EditableDocument 트레이트

EditableDocument 트레이트는 핵심 편집 계약을 정의합니다:

pub trait EditableDocument {
    fn get_info(&mut self) -> Result<DocumentInfo>;
    fn set_info(&mut self, info: DocumentInfo) -> Result<()>;
    fn page_count(&mut self) -> Result<usize>;
    fn get_page_info(&mut self, index: usize) -> Result<PageInfo>;
    fn remove_page(&mut self, index: usize) -> Result<()>;
    fn move_page(&mut self, from: usize, to: usize) -> Result<()>;
    fn duplicate_page(&mut self, index: usize) -> Result<usize>;
    fn save(&mut self, path: impl AsRef<Path>) -> Result<()>;
    fn save_with_options(&mut self, path: impl AsRef<Path>, options: SaveOptions) -> Result<()>;
}

DocumentEditor 전체 메서드 목록

아래 표는 Rust에서 DocumentEditor / Pdf 편집기의 전체 공개 메서드를 나열합니다. 각 행은 해당되는 경우 상세 가이드로 연결됩니다. 바인딩 지원 여부가 표시되어 있으며, Go / C# 예시는 각각의 페이지를 참조하세요.

메타데이터

메서드 Rust Python WASM Go C# 페이지
title / set_title 개요
author / set_author 개요
subject / set_subject 개요
keywords / set_keywords 개요
producer / set_producer 개요
creation_date / set_creation_date 개요
apply_metadata(info) 개요

페이지 작업

메서드 Rust Python WASM Go C# 페이지
remove_page / delete_page 페이지
move_page(from, to) 페이지
duplicate_page(i) 페이지
get_page_rotation / set_page_rotation 페이지
rotate_page_by(i, deg) 페이지
rotate_all_pages(deg) 페이지
get_page_media_box / set_page_media_box 페이지
get_page_crop_box / set_page_crop_box 페이지
crop_margins(l, r, t, b) 페이지
erase_region(page, rect) 페이지
erase_regions(page, rects) 페이지
clear_erase_regions(page) 페이지

병합 / 분할

메서드 Rust Python WASM Go C# 페이지
merge_from(path) 병합 및 분할
merge_pages_from(path, pages) 병합 및 분할
extract_pages(pages, output) 병합 및 분할
Merge([]paths) 최상위 병합 및 분할

양식

메서드 Rust Python WASM Go C# 페이지
get_form_fields() 양식
get_form_field_value(name) 양식
has_form_field(name) 양식
set_form_field_value(name, value) 양식
add_form_field(widget, page) 양식 생성
add_parent_field / add_child_field 양식 생성
remove_form_field(name) 양식
set_form_field_* (readonly, required, tooltip, rect, max_length, alignment, colors, flags) 양식
flatten_forms_on_page(page) 양식
flatten_forms() 양식
export_form_data_fdf(path) 양식
export_form_data_xfdf(path) 양식

주석

메서드 Rust Python WASM Go C# 페이지
flatten_page_annotations(page) 주석
flatten_all_annotations() 주석
is_page_marked_for_annotation_flatten(page) 주석
unmark_page_for_annotation_flatten(page) 주석

묵선 처리

메서드 Rust Python WASM Go C# 페이지
apply_page_redactions(page) 묵선 처리
apply_all_redactions() 묵선 처리
is_page_marked_for_redaction(page) 묵선 처리
unmark_page_for_redaction(page) 묵선 처리

XFA

메서드 Rust Python WASM Go C# 페이지
has_xfa() XFA 양식
analyze_xfa() XFA 양식
convert_xfa_to_acroform(opts) XFA 양식

저장

메서드 Rust Python WASM Go C# 페이지
save(path) 개요
save_with_options(path, opts) 암호화
save_encrypted(path, user, owner) 암호화
save_with_encryption(path, cfg) 암호화
save_async / SaveAsync 비동기

유틸리티 메서드 (Go 편의 기능)

Go에서 DocumentEditor 메서드로 노출된 것들; Rust에서는 editor.source()를 통해 동일한 기능 접근:

메서드 Rust Python WASM Go C#
IsModified is_modified() is_modified IsModified() IsModified
SourcePath source_path() source_path SourcePath() SourcePath
Version version() version() Version()
PageCount current_page_count() page_count() pageCount() PageCount() PageCount
RemoveHeaders / RemoveFooters / RemoveArtifacts
Close / Dispose Drop context manager free() Close() Dispose()

전체 편집 워크플로

이 예시는 완전한 편집 세션을 보여줍니다: 열기, 검사, 메타데이터 수정, 콘텐츠 편집, 저장.

Python

from pdf_oxide import PdfDocument

# Open the document
doc = PdfDocument("report.pdf")
print(f"Pages: {doc.page_count()}")

# Update metadata
doc.set_title("Annual Report 2025")
doc.set_author("Finance Team")

# Edit text on page 0
page = doc.page(0)
for text in page.find_text_containing("DRAFT"):
    page.set_text(text.id, "FINAL")
doc.save_page(page)

# Save
doc.save("report-final.pdf")

Rust

use pdf_oxide::api::Pdf;

let mut doc = Pdf::open("report.pdf")?;
println!("Pages: {}", doc.page_count()?);

// Update metadata
{
    let editor = doc.editor().unwrap();
    editor.set_title("Annual Report 2025");
    editor.set_author("Finance Team");
}

// Edit text on page 0
let mut page = doc.page(0)?;
let drafts = page.find_text_containing("DRAFT");
for t in &drafts {
    page.set_text(t.id(), "FINAL")?;
}
doc.save_page(page)?;

// Save
doc.save("report-final.pdf")?;

관련 페이지