使用PDFform表单形式来生成模板标签
在物流相关的项目中,制作一个派送标签是一个非常核心的功能之一。parcels现在与标签创建标签有关的方案大体有2个.
1 通过HTML文件来构建样式模板,然后使用wkhtmltopdf转为PDF.
2 使用itextpdf库以编码方式创建PDF.
这两个方案都有各自的优点和缺点。
第一个方案用HTML代码设计样式比较容易,转换成PDF的速度还可以。但是会存在一些样式上兼容性的问题。大体上需要通过不段的重复的调整和转换才能保证最终效果和需求上的一致。
(现在项目为了简化标签流程创作了拖动控件来创建HTML样式的WEB页面,但是最终样式的生成还是需要进行重复调整,编写代码调用方面也有点难度,因此基本上只局限于我们自己内单标签的使用。)
第二个方案很少用,毕竟使用代码来画PDF并没有办法可以实时预览样式,只能编译输出才能看到最终效果,而且代码的编写比较复杂。
为了更快捷创建自定义的PDF派送标签,这里建议使用PDFForm表单方式来创建PDF标签模板。
这个方案只需要简单的3个步骤就能完成一个PDF标签的模板制作和最终效果一样的项目需求。
1 使用PDFEdit把派送商提供的标签打开删掉需要替换的文本或者图片,如果无提供则使用此软件自己手动画一个模板。
2 用PDF软件把创建好的模板上,把需要输入文字或者图片的地方标上文本控件和图像控件对象。
3 通过代码方式把模板的控件对象进行文本填充和图像添加,然后保存成pdf文件即可。
这里需要用到2个软件 PDFEdit和万兴PDF专家(这个有替代软件,只要有创建表单功能即可比如 Adobe的pdf阅读器)。
下载连接: http://static.parcels.tech/PDF%E8%A1%A8%E5%8D%95%E5%A4%84%E7%90%86.rar
以下为具体制作流程:
第一步
打开PDFEdit把标签打开
去除需要替换的文本和调整样式(红色的地方是我去掉的文本和一维码图片)
第二步
这里使用万兴PDF专家打开处理好的PDF模板
在菜单栏上找到表单选择,然后在切换好的页面上单击编辑表单
然后我们就能在pdf上面画控件了。这里主要用到的是文本控件和图像控件
下图是我把控件画好的样式,记得要给控件重新命名,编码的时候需要用到。
第三步
编写代码直接把需要填入控件的文本写进去然后保存即可。
public static void main(String[] args) throws Exception {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
//要插入的数据
Map<String, Object> data = new HashMap<>();
data.put("weight", "165");
data.put("count", "5");
data.put("sortation", "TEST-IT");
data.put("codeNum", "SV91858001IT");
data.put("date", "11:22 26/10/2020");
//初始化itext
//设置编码
BaseFont baseFont = BaseFont.createFont();
PdfReader pdfReader = new PdfReader("f:\\temp.pdf");
PdfStamper pdfStamper = new PdfStamper(pdfReader, byteArrayOutputStream);
AcroFields form = pdfStamper.getAcroFields();
form.addSubstitutionFont(baseFont);
//写入数据
for (String key : data.keySet()) {
String value = data.get(key).toString();
//key对应模板数据域的名称
form.setField(key, value);
}
String base64 = BarcodeUtil.createBarcode("SV91858001IT");
// 添加图片
form.setField("image", base64);
//设置不可编辑
pdfStamper.setFormFlattening(true);
pdfStamper.close();
FileOutputStream fileOutputStream = new FileOutputStream("f:\\ok.pdf");
fileOutputStream.write(byteArrayOutputStream.toByteArray());
fileOutputStream.close();
byteArrayOutputStream.close();
}