В последнее время в проекте необходимо реализовать функцию скачивания 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 документу
- 2 Сохраните документ Word в виде 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());