
PDF 양식이 작성되면 입력된 값은 시각적 레이아웃과 결합하여 봉인된 결과물이 됩니다. 이러한 항목을 다른 템플릿으로 마이그레이션하려면 모든 필드를 손으로 다시 입력해야 합니다. 해결책은 양식 데이터를 이식 가능한 자산으로 취급하는 것입니다. 즉, 필드 값을 독립형 데이터 파일로 추출한 다음, 양식의 빈 복사본에 다시 넣어 모든 항목을 한 번의 자동 작업으로 재현하는 것입니다. 이 내보내기-가져오기 주기를 Spire.PDF for JavaScript가 PdfFormWidget.ExportData 및 PdfFormWidget.ImportData를 통해 제공합니다.
두 메서드 모두 XML, FDF, XFDF의 세 가지 파일 형식을 사용할 수 있습니다. 이들 사이를 전환하는 것은 DataFormat 열거형 값을 변경하는 것에 불과합니다. 호출 방식은 동일하게 유지되며, 출력 파일의 디스크상 구조만 변경됩니다. Spire.PDF for JavaScript는 WebAssembly 위에서 전적으로 브라우저에서 실행되므로 전체 왕복 작업이 가상 파일 시스템(VFS)을 통해 로컬로 실행되며, 백엔드 서버가 관여하지 않고 문서가 클라이언트를 벗어나지 않습니다.
이 문서에서는 전체 데이터 흐름을 살펴봅니다.
- 양식 데이터 내보내기 — 작성된 양식에서 필드 값을 추출합니다
- 양식 데이터 가져오기 — 해당 값을 빈 양식에 다시 채웁니다
설치 및 프로젝트 설정은 React 프로젝트에 Spire.PDF for JavaScript 통합을 참조하세요. 아래 예제에서는 Spire.PDF가 설치되어 있고 WebAssembly 모듈이 초기화되었다고 가정합니다.
한눈에 보는 세 가지 양식 데이터 형식
코드를 살펴보기 전에 ExportData 및 ImportData가 사용하는 세 가지 형식을 이해하면 도움이 됩니다. 세 가지 모두 동일한 페이로드(필드 이름/값 쌍의 집합)를 전달하지만 패키징 방식이 다릅니다. 처음부터 올바른 형식을 선택하면 나중에 데이터 파일을 공유하거나 검사하거나 다른 도구에 넣어야 할 때 번거로움을 줄일 수 있습니다.
| 형식 | 열거형 값 | 파일 구조 | 사람이 읽을 수 있음 | 최적 용도 |
|---|---|---|---|---|
| XML | DataFormat.Xml |
Adobe 양식 데이터 XML. 필드 이름이 요소 이름이 되고 값은 요소 내용으로 위치합니다 | 예 | 빠른 검사, 디버깅, 간단한 도구 |
| FDF | DataFormat.Fdf |
Forms Data Format. %FDF-로 시작하는 텍스트 구조이며, /T는 필드 이름을, /V는 값을 담습니다 |
아니요 | 프로그램 간 간결한 전송 |
| XFDF | DataFormat.XFdf |
XFDF, 표준 XML. 필드마다 하나의 <field name="…">가 있으며, 값은 <value> 안에 있습니다 |
예 | 버전 관리, 시스템 간 교환 |
세 가지 모두 필드 값과 관련해 손실이 없습니다 — 내보내기나 가져오기 중에 삭제되거나 변환되는 항목은 없습니다. 이들 중 선택은 전적으로 워크플로 적합성에 관한 것이며, 아래의 형식 선택 가이드에서 다시 다룹니다.
PDF 양식 데이터 내보내기
왕복의 첫 번째 절반은 추출입니다. PdfFormWidget.ExportData는 양식의 모든 필드 값을 가져와 단일 데이터 파일에 기록합니다. 두 번째 인수인 DataFormat 열거형은 기록할 형식을 제어합니다. 세 번째 인수는 양식 이름입니다. 이름이 없는 AcroForm의 경우 빈 문자열을 전달합니다.
아래 예제에서는 작성된 고객 정보 양식을 로드하고, 양식 핸들을 PdfFormWidget로 감싼 다음, 필드 값을 XML 파일로 내보냅니다. FDF 및 XFDF 변형은 주석 처리된 줄로 포함되어 있습니다. 다른 항목을 건드리지 않고 형식을 전환하려면 아무 줄이나 주석 해제하세요.
function App() {
const exportFormData = async () => {
// Get the Spire.PDF WASM module
const pdfModule = window.wasmModule?.spirepdf;
// Check that the module is ready
if (!pdfModule) {
alert('Spire.PDF is not ready yet');
return;
}
// Load the PDF file to be exported into the VFS
const inputFileName = 'CustomerInformationForm.pdf';
await window.spire.FetchFileToVFS(inputFileName, "", `${process.env.PUBLIC_URL}/data/`);
// Create a PdfDocument object and load the PDF document
const doc = new pdfModule.PdfDocument();
doc.LoadFromFile(inputFileName);
// Build a PdfFormWidget from the document's form handle to reach the data export API
const formWidget = new pdfModule.PdfFormWidget(doc.Form.H);
// This demo exports XML
const dataFiles = [
{ fileName: 'FormData.xml', format: pdfModule.DataFormat.Xml },
// { fileName: 'FormData.fdf', format: pdfModule.DataFormat.Fdf },
// { fileName: 'FormData.xfdf', format: pdfModule.DataFormat.XFdf },
];
for (const item of dataFiles) {
// The third parameter is the form name; pass an empty string for an unnamed form
formWidget.ExportData(item.fileName, item.format, '');
}
doc.Close();
// Read the generated file from the VFS and trigger the download
for (const item of dataFiles) {
const fileArray = window.dotnetRuntime.Module.FS.readFile(item.fileName);
const blob = new Blob([fileArray], { type: 'application/octet-stream' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = item.fileName;
a.click();
URL.revokeObjectURL(url);
}
};
return (
<div style={{ textAlign: 'center', height: '300px' }}>
<h1>Export Form Data</h1>
<button onClick={exportFormData}>
Export
</button>
</div>
);
}
export default App;
내보내기 호출이 완료되면 데이터 파일은 가상 파일 시스템에 저장됩니다. 그런 다음 코드는 VFS에서 파일을 다시 읽고 브라우저 다운로드를 트리거하여 파일을 저장, 공유 또는 다른 양식 데이터와 함께 보관할 수 있게 합니다.

PDF 양식 데이터 가져오기
왕복의 두 번째 절반은 데이터를 다시 채우는 작업입니다. PdfFormWidget.ImportData는 데이터 파일을 읽고 각 값을 이름으로 일치하는 양식 필드에 다시 기록합니다. DataFormat 매개변수는 파서에게 파일 내용을 해석하는 방법을 알려줍니다. 파일 확장자와는 아무 관련이 없으므로 선언된 형식은 파일의 실제 형식과 일치해야 합니다.
여기서 대상은 원본 양식의 빈 복사본입니다. 템플릿은 비어 있는 상태로 나가고, 데이터 파일이 돌아오면 모든 필드가 한 번에 채워집니다. 수동으로 다시 입력할 필요도, 필드별로 복사할 필요도, 모든 내용을 두 번째로 입력할 필요도 없습니다.
function App() {
const importFormData = async () => {
// Get the Spire.PDF WASM module
const pdfModule = window.wasmModule?.spirepdf;
// Check that the module is ready
if (!pdfModule) {
alert('Spire.PDF is not ready yet');
return;
}
// Load the blank form to be filled into the VFS
const inputFileName = 'BlankCustomerInformationForm.pdf';
await window.spire.FetchFileToVFS(inputFileName, "", `${process.env.PUBLIC_URL}/data/`);
// This demo refills from the XML data file
const dataFiles = [
{ fileName: 'FormData.xml', format: pdfModule.DataFormat.Xml, outputFileName: 'ImportedXMLData.pdf' },
// { fileName: 'FormData.fdf', format: pdfModule.DataFormat.Fdf, outputFileName: 'ImportedFDFData.pdf' },
// { fileName: 'FormData.xfdf', format: pdfModule.DataFormat.XFdf, outputFileName: 'ImportedXFDFData.pdf' },
];
for (const item of dataFiles) {
// The data file also has to be loaded into the VFS first
await window.spire.FetchFileToVFS(item.fileName, "", `${process.env.PUBLIC_URL}/data/`);
const doc = new pdfModule.PdfDocument();
doc.LoadFromFile(inputFileName);
// Read the data file and write the values back into the fields by name
const formWidget = new pdfModule.PdfFormWidget(doc.Form.H);
formWidget.ImportData(item.fileName, item.format);
doc.SaveToFile(item.outputFileName);
doc.Close();
// Read the generated file from the VFS and trigger the download
const fileArray = window.dotnetRuntime.Module.FS.readFile(item.outputFileName);
const blob = new Blob([fileArray], { type: 'application/pdf' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = item.outputFileName;
a.click();
URL.revokeObjectURL(url);
}
};
return (
<div style={{ textAlign: 'center', height: '300px' }}>
<h1>Import Form Data</h1>
<button onClick={importFormData}>
Import
</button>
</div>
);
}
export default App;
가져오기 호출이 완료되면 이전에 비어 있던 양식이 완전히 채워지고 저장하거나 표시할 준비가 됩니다. 결과는 데이터 파일에서 모든 필드가 채워진 새 PDF입니다.

올바른 데이터 형식 선택
세 가지 형식 모두 동일한 필드 값을 담고 있으므로 결정은 데이터 충실도보다는 구조와 도구 지원에 달려 있습니다. 다음은 양식 데이터 왕복 맥락에서 각 형식을 고려하는 방법입니다.
-
FDF는 가장 작은 파일을 생성합니다.
%FDF-로 시작하며/T가 필드 이름을,/V가 값을 담는 간결한 텍스트 표기법을 사용합니다. 따라서 양식 처리 프로그램 간에 데이터를 전달하는 데 효율적이지만, 내용을 사람이 쉽게 읽을 수 없고 텍스트 도구나 버전 관리 시스템과 잘 맞지 않습니다. -
XFDF는 필드마다 하나의
<field>요소를 갖는 표준 XML입니다. 잘 구성된 XML이므로 일반 텍스트 도구로 차이를 비교하고, 병합하고, 검사할 수 있어 데이터 파일이 버전 관리에 들어가거나 사람이 검토해야 하거나 다른 시스템과 상호 운용해야 할 때 가장 안전한 선택입니다. - XML(Adobe 양식 데이터 XML)은 필드 이름을 요소 이름에 직접 넣어 세 가지 중 가장 간단한 구조를 제공합니다. 별도의 복잡한 과정 없이 읽을 수 있는 필드 이름과 값 목록을 원할 때 이상적입니다.
요약하자면, 단일 프로그램 내에서 이루어지는 왕복에는 FDF를 사용하고, 파일이 도구나 팀 경계를 넘을 때는 XFDF를 사용하며, 가독성이 최우선일 때는 XML을 사용하세요.
자주 묻는 질문
가져온 후 일부 필드가 여전히 비어 있음
원인: ImportData는 필드 이름으로 일치시키므로 데이터 파일의 이름은 대소문자와 공백을 포함해 양식의 필드 이름과 정확히 일치해야 합니다. 일치하지 않는 필드는 조용히 건너뜁니다. 불일치를 나타내는 오류나 반환 값은 없습니다. 이름이 일치하는 필드만 값을 받습니다.
해결 방법: 가져오기 전에 양식의 필드 컬렉션을 순회하며 실제 이름을 출력한 다음 데이터 파일과 비교하세요.
const fields = formWidget.FieldsWidget;
for (let i = 0; i < fields.Count; i++) {
console.log(fields.get_Item({ index: i }).Name);
}
가져오기 시 Xml_MessageWithErrorPosition 또는 "not a valid FDF file" 오류 발생
원인: ImportData는 두 번째 매개변수로 지정된 형식에 따라 파일을 구문 분석하며 파일 확장자를 검사하지 않습니다. 내용이 선언된 형식과 일치하지 않으면 구문 분석이 즉시 실패합니다. XML 파일은 Xml_MessageWithErrorPosition, Xml_InvalidRootData를 보고하고, FDF가 아닌 파일은 The source is not a valid FDF file because it does not start with "%FDF-"를 보고합니다.
해결 방법: 파일의 실제 내용과 일치하는 DataFormat을 전달하고, 다른 형식으로 다시 저장된 파일이 아니라 원래 내보낸 데이터 파일을 사용하세요.