用java写一段通过word模板生成docx文件并转pdf的代码并可通过浏览器下载
时间: 2024-05-13 08:14:11 浏览: 185
基于java的word转pdf工具
以下是一个通过Word模板生成DOCX文件并转换为PDF,并提供浏览器下载的Java代码示例:
```java
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
import org.apache.poi.xwpf.usermodel.XWPFTableRow;
import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.XmlOptions;
import org.docx4j.Docx4J;
import org.docx4j.convert.out.pdf.PdfConversion;
import org.docx4j.convert.out.pdf.viaXSLFO.ConversionOptions;
import org.docx4j.fonts.IdentityPlusMapper;
import org.docx4j.fonts.Mapper;
import org.docx4j.model.structure.PageSizePaper;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart;
import org.docx4j.wml.CTBorder;
import org.docx4j.wml.CTBorderPr;
import org.docx4j.wml.CTTbl;
import org.docx4j.wml.CTTblBorders;
import org.docx4j.wml.CTTblGrid;
import org.docx4j.wml.CTTblLayoutType;
import org.docx4j.wml.CTTblPr;
import org.docx4j.wml.CTTblWidth;
import org.docx4j.wml.ObjectFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
public class WordToPdfController {
@RequestMapping(value = "/word-to-pdf", method = RequestMethod.GET)
public void generatePdf(HttpServletResponse response) throws Exception {
// 获取Word模板文件
File templateFile = new File("template.docx");
FileInputStream in = new FileInputStream(templateFile);
// 替换Word中的变量
Map<String, String> variables = new HashMap<>();
variables.put("name", "John Doe");
variables.put("age", "30");
variables.put("address", "123 Main Street");
byte[] docxBytes = replaceVariables(in, variables);
// 将DOCX文件转换为PDF
byte[] pdfBytes = convertToPdf(docxBytes);
// 设置响应头
response.setContentType("application/pdf");
response.setHeader("Content-Disposition", "attachment; filename=output.pdf");
// 将PDF文件写入响应体
OutputStream out = response.getOutputStream();
out.write(pdfBytes);
out.flush();
out.close();
}
private byte[] replaceVariables(InputStream in, Map<String, String> variables) throws Exception {
// 加载Word模板文件
WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(in);
MainDocumentPart documentPart = wordMLPackage.getMainDocumentPart();
// 获取文档中的所有段落和表格
java.util.List<Object> paragraphsAndTables = documentPart.getContent();
// 遍历文档中的所有段落和表格
for(Object paragraphOrTable : paragraphsAndTables) {
if(paragraphOrTable instanceof XWPFParagraph) {
// 如果是段落,则替换其中的变量
XWPFParagraph paragraph = (XWPFParagraph) paragraphOrTable;
for(XWPFRun run : paragraph.getRuns()) {
String text = run.getText(0);
if(text != null) {
for(Map.Entry<String, String> entry : variables.entrySet()) {
if(text.contains(entry.getKey())) {
text = text.replace(entry.getKey(), entry.getValue());
run.setText(text, 0);
}
}
}
}
} else if(paragraphOrTable instanceof XWPFTable) {
// 如果是表格,则遍历其中的单元格并替换其中的变量
XWPFTable table = (XWPFTable) paragraphOrTable;
for(XWPFTableRow row : table.getRows()) {
for(XWPFTableCell cell : row.getTableCells()) {
for(XWPFParagraph paragraph : cell.getParagraphs()) {
for(XWPFRun run : paragraph.getRuns()) {
String text = run.getText(0);
if(text != null) {
for(Map.Entry<String, String> entry : variables.entrySet()) {
if(text.contains(entry.getKey())) {
text = text.replace(entry.getKey(), entry.getValue());
run.setText(text, 0);
}
}
}
}
}
}
}
}
}
// 将修改后的文档保存为字节数组
ByteArrayOutputStream out = new ByteArrayOutputStream();
Docx4J.save(wordMLPackage, out);
return out.toByteArray();
}
private byte[] convertToPdf(byte[] docxBytes) throws Exception {
// 加载DOCX文件
ByteArrayInputStream in = new ByteArrayInputStream(docxBytes);
WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(in);
// 设置字体映射
Mapper fontMapper = new IdentityPlusMapper();
wordMLPackage.setFontMapper(fontMapper);
// 设置页面大小和边距
PageSizePaper pageSizePaper = new PageSizePaper();
pageSizePaper.setCode("A4");
wordMLPackage.getDocumentModel().getSections().get(0).getPageDimensions().setPageSize(pageSizePaper);
wordMLPackage.getDocumentModel().getSections().get(0).getPageDimensions().setMarginTop(1440);
wordMLPackage.getDocumentModel().getSections().get(0).getPageDimensions().setMarginBottom(1440);
wordMLPackage.getDocumentModel().getSections().get(0).getPageDimensions().setMarginLeft(1440);
wordMLPackage.getDocumentModel().getSections().get(0).getPageDimensions().setMarginRight(1440);
// 获取文档中的所有表格
java.util.List<Object> tables = wordMLPackage.getMainDocumentPart().getContent();
for (Object obj : tables) {
if (obj instanceof javax.xml.bind.JAXBElement
&& ((javax.xml.bind.JAXBElement<?>) obj).getDeclaredType().getName().equals("org.docx4j.wml.Tbl")) {
javax.xml.bind.JAXBElement<org.docx4j.wml.Tbl> element = (javax.xml.bind.JAXBElement<org.docx4j.wml.Tbl>) obj;
org.docx4j.wml.Tbl table = element.getValue();
// 设置表格边框
CTTbl ctTbl = table.getCTTbl();
CTTblPr tblPr = ctTbl.getTblPr();
if (tblPr == null) {
tblPr = new CTTblPr();
ctTbl.setTblPr(tblPr);
}
CTTblBorders borders = tblPr.getTblBorders();
if (borders == null) {
borders = new CTTblBorders();
tblPr.setTblBorders(borders);
}
CTBorder border = new CTBorder();
border.setColor("#000000");
border.setSz(new BigInteger("2"));
CTBorderPr borderPr = new CTBorderPr();
borderPr.setTop(border);
borderPr.setBottom(border);
borderPr.setLeft(border);
borderPr.setRight(border);
borders.setTop(borderPr);
borders.setBottom(borderPr);
borders.setLeft(borderPr);
borders.setRight(borderPr);
// 设置表格宽度
CTTblGrid tblGrid = ctTbl.getTblGrid();
if (tblGrid == null) {
tblGrid = new CTTblGrid();
ctTbl.setTblGrid(tblGrid);
}
for (int i = 0; i < table.getContent().size(); i++) {
Object row = table.getContent().get(i);
if (row instanceof javax.xml.bind.JAXBElement
&& ((javax.xml.bind.JAXBElement<?>) row).getDeclaredType().getName().equals("org.docx4j.wml.Tr")) {
javax.xml.bind.JAXBElement<org.docx4j.wml.Tr> rowElement = (javax.xml.bind.JAXBElement<org.docx4j.wml.Tr>) row;
org.docx4j.wml.Tr tr = rowElement.getValue();
for (int j = 0; j < tr.getContent().size(); j++) {
Object cell = tr.getContent().get(j);
if (cell instanceof javax.xml.bind.JAXBElement
&& ((javax.xml.bind.JAXBElement<?>) cell).getDeclaredType().getName().equals("org.docx4j.wml.Tc")) {
javax.xml.bind.JAXBElement<org.docx4j.wml.Tc> cellElement = (javax.xml.bind.JAXBElement<org.docx4j.wml.Tc>) cell;
org.docx4j.wml.Tc tc = cellElement.getValue();
CTTblWidth tblWidth = new CTTblWidth();
tblWidth.setType("dxa");
tblWidth.setW(BigInteger.valueOf(1000));
tc.getTcPr().setTcW(tblWidth);
}
}
}
}
}
}
// 将文档转换为PDF
ConversionOptions conversionOptions = new ConversionOptions();
conversionOptions.setQuality(PdfConversionQualityEnum.PDF_A_1_B);
OutputStream out = new ByteArrayOutputStream();
PdfConversion converter = new org.docx4j.convert.out.pdf.viaXSLFO.Conversion(wordMLPackage);
converter.output(out, conversionOptions);
return ((ByteArrayOutputStream) out).toByteArray();
}
}
```
在上述代码中,我们首先通过`replaceVariables()`方法将Word模板中的变量替换为实际值,然后通过`convertToPdf()`方法将DOCX文件转换为PDF。最后,我们将PDF文件写入响应体并设置响应头,使得浏览器可以下载该文件。注意,这里我们使用了`docx4j`和`poi`两个开源库来处理Word和PDF文件。
阅读全文