1. Origines
En raison des besoins de l'entreprise, j'ai besoin de générer un rapport PDF à partir d'une partie des données du programme pour le téléchargement et la navigation
2. Méthode de mise en œuvre
- Concevez un modèle pdf, vous pouvez modifier le modèle via des outils d'édition pdf, et les éditeurs pdf prenant en charge les formulaires d'édition sur le marché peuvent être utilisés, tels que Adobe Acrobat DC, Wondershare PDF, QuickPDF, etc.
- Définissez le nom correspondant de la cellule de formulaire via l'édition de formulaire et utilisez-le pour l'affectation de programme ultérieure
- Vous pouvez régler le texte pour qu'il soit centré horizontalement (mais les programmes actuels ne prennent pas en charge le centrage vertical, si vous voulez le réaliser plus tard, vous devez commencer par le programme)
- Après avoir défini le texte, vous pouvez commencer à écrire l'affectation du programme (code principal)
//创建A4大小的文档
Document document = new Document(PageSize.A4);
document.open();
//读取现有模板内容(templateFile为模板路径)
PdfReader reader = new PdfReader(FileUtil.path(templateFile));
//创建输出流
ByteArrayOutputStream bos = new ByteArrayOutputStream();
//实例化PdfStamper准备编辑pdf内容
PdfStamper ps = new PdfStamper(reader, bos);
//获取表单所有元素
AcroFields fields = ps.getAcroFields();
//设置具体字体格式编码,不设置的话中文可能会不显示
BaseFont baseFont = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
/添加替换元素
fields.addSubstitutionFont(baseFont);
//data是一个Map<String,String> 主要存储 key 表单模板中的单元格名 value为想要赋的值,遍历
for (String key : data.keySet()) {
String value = data.get(key);
//个人逻辑,参考即可,对于特定的表单元素设置不同的字体格式大小
if("r_game".equals(key)) {
//设置格式
fields.setFieldProperty(key, "textsize", 35f, null);
}else if("i_title".equals(key)) {
fields.setFieldProperty(key, "textsize", 20f, null);
}else if ("r_image".equals(key)){
if (!StringUtils.isEmpty(value)){
//设置添加图片
addImageToPdf(fields, ps,value);
continue;
}
}else if ("r_project_name".equals(key)||"r_header".equals(key)||"r_appraisal".equals(key)){
//将文本垂直居中添加
addTextToPdfCenter(fields,ps,value,key,baseFont);
continue;
}
else {
fields.setFieldProperty(key, "textsize", defaultSize, null);
}
fields.setField(key, value);
}
//生成的文档可编辑
ps.setFormFlattening(true);
//关闭操作
ps.close();
//将编辑后的文件输出到outputFile路径下
OutputStream fos = new FileOutputStream(FileUtil.path(outputFile));
fos.write(bos.toByteArray());
bos.close();
fos.close();
document.close();
- Population d'images au modèle de tableau
private static void addImageToPdf(AcroFields form, PdfStamper stamper, String filePath) throws DocumentException, IOException {
// 通过域名获取所在页和坐标,左下角为起点
int pageNo = form.getFieldPositions("r_image").get(0).page;
Rectangle signRect = form.getFieldPositions("r_image").get(0).position;
float x = signRect.getLeft()+signRect.getRight();
float y = signRect.getTop();
// 读图片
Image image = Image.getInstance(filePath);
// 获取操作的页面
PdfContentByte under = stamper.getOverContent(pageNo);
// 根据域的大小缩放图片
image.scaleToFit(signRect.getWidth()/4, signRect.getHeight()/4);
// 添加图片并设置位置(个人通过此设置使得图片垂直水平居中,可参考,具体情况已实际为准)
image.setAbsolutePosition(x/2-image.getWidth()/2, y/2+image.getHeight());
under.addImage(image);
}
- Le texte n'est pas centré verticalement comme suit
Centrer le texte verticalement
Centrer verticalement en obtenant la position du modèle, puis en refactorisant les cellules du formulaire
private static void addTextToPdfCenter(AcroFields form, PdfStamper stamper, String text,String fieldName,BaseFont baseFont){
// 通过模板表单单元格名获取所在页和坐标,左下角为起点
int pageNo = form.getFieldPositions(fieldName).get(0).page;
Rectangle signRect = form.getFieldPositions(fieldName).get(0).position;
// 获取操作的页面
PdfContentByte contentByte = stamper.getOverContent(pageNo);
//创建表单
PdfPTable table = new PdfPTable(1);
//获取当前模板表单宽度
float totalWidth = signRect.getRight() - signRect.getLeft() - 1;
//设置新表单宽度
table.setTotalWidth(totalWidth);
//设置中文格式
Font font = new Font(baseFont);
//设置单元格格式
PdfPCell cell = new PdfPCell(new Phrase(text,font));
//设置单元格高度
cell.setFixedHeight(signRect.getTop()-signRect.getBottom()-1);
cell.setBorderWidth(0);
//设置垂直居中
cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
//设置水平居中
cell.setHorizontalAlignment(Element.ALIGN_CENTER);
//添加到表单中
table.addCell(cell);
//写入pdf
table.writeSelectedRows(0, -1, signRect.getLeft(), signRect.getTop(), contentByte);
}
L'effet est le suivant