Java для создания PDF-документов

Java

В последнее время в проекте необходимо реализовать функцию скачивания PDF.Поскольку опыта в этой области нет, поиск актуальной информации в Интернете занял много времени. После сортировки я обнаружил, что для достижения этой функции существует несколько следующих фреймворков.

1. Поддержка фреймворка с открытым исходным кодом

  • iText генерирует документы PDF, а также поддерживает преобразование файлов XML и HTML в файлы PDF;
  • Apache PDFBox, создание и объединение PDF-документов;
  • docx4j, генерирует документы docx, pptx, xlsx, поддерживает преобразование в формат PDF.

сравнивать:

  • Лицензия с открытым исходным кодом iText — это AGPL, а две другие лицензии — это лицензия Apache License v2.0.
  • Использование PDFBox для создания PDF похоже на рисование изображения: текст и изображения рисуются в соответствии с координатами страницы и должны быть вручную перенесены в соответствии с количеством слов.
  • docx4j используется для создания документов docx и предоставляет функцию преобразования документов WORD в документы PDF, но не может напрямую генерировать документы PDF.

2. План реализации

сложный формат простой формат
Большой объем данных docx4j+freemarker docx4j или PDFBox
небольшой объем данных docx4j PDFBox

2.1 Генерация PDF из чистых данных

1.docx4j, подходит для создания PDF-документов с простым или сложным форматом и небольшим объемом данных; 2. Apache PDFBox, подходящий для создания PDF-документов с простым форматом и небольшим объемом данных.

1. docx4j docx4j — это библиотека Java с открытым исходным кодом для создания файлов Microsoft Open XML (Word docx, Powerpoint pptx и Excel xlsx) и управления ими. Он похож на Microsoft OpenXML SDK, но для Java. docx4j использует JAXB для создания представлений объектов в памяти, программистам нужно потратить время, чтобы понять JAXB и файловую структуру Open XML.

// word对象
WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.createPackage();
// 文档主体
MainDocumentPart mainDocumentPart = wordMLPackage.getMainDocumentPart();
// 换行符
Br br = objectFactory.createBr();
// 段落
P p = objectFactory.createP();
// 段落设置
PPr ppr = objectFactory.createPPr();
// 文字位置
Jc jc = new Jc();
jc.setVal(je);
ppr.setJc(jc);
// 行设置
RPr rpr = objectFactory.createRPr();
// 字体设置
RFonts rFonts = objectFactory.createRFonts();
rFonts.setAscii("Times New Roman");
rFonts.setEastAsia("宋体");
rpr.setRFonts(rFonts);
// 行
R r = objectFactory.createR();
// 文本
Text text = objectFactory.createText();
text.setValue("这是一段普通文本");
r.setRPr(rpr);
r.getContent().add(br);
r.getContent().add(text);
p.getContent().add(r);
p.setPPr(ppr);
// 添加到正文中
mainDocumentPart.addObject(p);
// 导出
//..

2. Апач PDFBox Apache PDFBox — это инструмент Java с открытым исходным кодом для обработки документов PDF. Этот проект позволяет создавать новые документы PDF, обрабатывать существующие документы и извлекать содержимое из документов. Apache PDFBox также включает в себя несколько утилит командной строки.

String formTemplate = "/Users/xiaoming/Desktop/test_pdfbox.pdf";
// 定义文档对象
PDDocument document = new PDDocument();
// 定义一页,大小A4
PDPage page = new PDPage(PDRectangle.A4);
document.addPage(page);
// 获取字体
PDType0Font font = PDType0Font.load(document, new File("/Users/xiaoming/work/tmp/simsun.ttf"));
// 定义页面内容流
PDPageContentStream stream = new PDPageContentStream(document, page);
// 设置字体及文字大小
stream.setFont(font, 12);
// 设置画笔颜色
stream.setNonStrokingColor(Color.BLACK);
// 添加矩形
stream.addRect(29, 797, 100, 14);
// 填充矩形
stream.fill();
stream.setNonStrokingColor(Color.BLACK);
// 文本填充开始
stream.beginText();
// 设置行距
stream.setLeading(18f);
// 设置文字位置
stream.newLineAtOffset(30, 800);
// 填充文字
stream.showText("呵呵");
// 换行
stream.newLine();
stream.showText("哈哈");
stream.newLine();
stream.showText("嘻嘻");
// 文本填充结束
stream.endText();
// 关闭流
stream.close();
// 保存
document.save(formTemplate);
// 释放资源
document.close();

2.2 Шаблон + данные для создания PDF

FreeMarker+docx4j, подходит для создания документов PDF со сложными форматами и большими объемами данных.

Apache FreeMarker — это механизм шаблонов для создания текстового вывода (веб-страницы HTML, электронные письма, файлы конфигурации, исходный код и т. д.) из шаблонов и измененных данных. Шаблоны написаны на языке шаблонов FreeMarker (FTL), простом специализированном языке.

После Office 2003 Word можно хранить в текстовом формате XML. Сначала преобразуйте создаваемый PDF-файл в документ Word, затем сохраните его как текст XML, заполните данные в текст XML с помощью механизма шаблонов и, наконец, преобразуйте его в документ PDF в обратном порядке. Проще говоря, это процесс PDF->Word->XML->Word->PDF.

шаг описывать инструмент
1 word -> xml руководство
2 xml -> ftl руководство, ссылка«Введение в общие теги для документов Word в формате XML»
3 ftl + obj = xml freemarker
4 xml -> pdf docx4j
шаг
  • 1 Сделайте слово (docx) соответствующим pdf документу
    简历.png
  • 2 Сохраните документ Word в виде XML-файла.
    另存为xml
  • 3 Превратите файл xml в файл шаблона freemarker (ftl).
    制作模版文件
  • 4 Соберите файлы данных и ftl в текст xml
Map<String, Object> map = new HashMap<>();
map.put("name", "小明");
map.put("address", "北京市朝阳区");
map.put("email", "xiaoming@abc.com");
StringWriter stringWriter = new StringWriter();
BufferedWriter writer = new BufferedWriter(stringWriter);
template.process(map, writer);
String xmlStr = stringWriter.toString();
  • 5 Загрузите текст xml как объект документа Word, используя docx4j
ByteArrayInputStream in = new ByteArrayInputStream(xmlStr.getBytes());
WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(in);
  • 6 Используйте docx4j для преобразования документов Word в документы PDF.
String outputfilepath = "/Users/xiaoming/简历.pdf";
FileOutputStream os = new FileOutputStream(new File(outputFilePath));
FOSettings foSettings = Docx4J.createFOSettings();
foSettings.setWmlPackage(wordMLPackage);
Docx4J.toFO(foSettings, os, Docx4J.FLAG_EXPORT_PREFER_XSL);
// Docx4J.toPDF(wordMLPackage, new FileOutputStream(new File(outputfilepath)));

2.3 Слово в PDF

docx4j

WordprocessingMLPackage mlPackage = WordprocessingMLPackage.load(new File("abc.docx"));
Mapper fontMapper = new IdentityPlusMapper();  
// fontMapper.put("华文行楷", PhysicalFonts.get("STXingkai"));  
mlPackage.setFontMapper(fontMapper);  
OutputStream os = new java.io.FileOutputStream("abc.pdf");    
FOSettings foSettings = Docx4J.createFOSettings();  
foSettings.setWmlPackage(mlPackage);  
Docx4J.toFO(foSettings, os, Docx4J.FLAG_EXPORT_PREFER_XSL);  

2.4 Объединение нескольких PDF-файлов

Apache PDFBox, объединение нескольких PDF-документов

String folderName = "/Users/xiaoming/pdfs";
String destPath = "/Users/xiaoming/all.pdf";
PDFMergerUtility mergePdf = new PDFMergerUtility();
String[] filesInFolder = getFiles(folderName);
Arrays.sort(filesInFolder, new Comparator<String>() {
      @Override
      public int compare(String o1, String o2) {
          return o1.compareTo(o2);
      }
});
for (int i = 0; i < filesInFolder.length; i++) {
     mergePdf.addSource(folderName + File.separator + filesInFolder[i]);
}
mergePdf.setDestinationFileName(destPath);
mergePdf.mergeDocuments(MemoryUsageSetting.setupMainMemoryOnly());

образец кода

GitHub.com/Брэндон Уайт/…