java使用itext生成pdf
一、利用Adobe Acrobat DC软件创建pdf模板
备好Adobe Acrobat DC软件
1.excel/jpg/png文件转pdf文件
右击打开我们要转换的文件
2.然后点击 添加 域
3.可以看到域的名字
4.调整字体大小/对齐方式等
5.保存
二,代码部分
首先
上依赖
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>${com.itextpdf.version}</version>
</dependency>
Controller
@PostMapping(value = "printlabel/pallet", produces = MediaType.APPLICATION_PDF_VALUE)
@ApiOperation(value = "打印托盘码", produces = MediaType.APPLICATION_PDF_VALUE)
public void printlabelPallet(@ApiParam @Valid @RequestBody PalletPrintRequest request, HttpServletResponse response) throws Exception {
labelService.printlabelPallet(request, response);
}
Service
@Override
@Lock4j
@Transactional(rollbackFor = Exception.class)
public void printlabelPallet(PalletPrintRequest request, HttpServletResponse response) throws Exception {
Crossdock crossdock = new Crossdock();
CrossdockPlanConsignee consignee = new CrossdockPlanConsignee();
CrossdockPlan plan = new CrossdockPlan();
//暂存
if (request.getIsTemp()){
crossdock = crossdockService.getByFieldValue(request.getOrderNo(), Crossdock::getOrderNo);
}else{
plan = planService.getByFieldValue(request.getPlanNo(),CrossdockPlan::getPlanNo);
if (ObjectUtils.isEmpty(plan)){
throw new ApiException(ResultCode.PARAMES_INVALID,"plan not found");
}
crossdock = crossdockService.getValidById(plan.getOrderId());
consignee = planConsigneeService.getByFieldValue(plan.getId(), CrossdockPlanConsignee::getPlanId);
}
Customer customer = customerService.getValidById(crossdock.getCustomerId());
//托盘标号
String consigneeName = consignee.getName() != null ? consignee.getName() : "";
if (request.getIsCustomize() && StringUtils.isNotBlank(request.getPalletNo())){
consigneeName = request.getPalletNo();
}else if (request.getIsTemp()) {
consigneeName += crossdock.getOrderNo();
consigneeName += LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyMMdd"));
String redisKey = redisService.genKey(new String[]{NoRules.class.getSimpleName()}, consigneeName);
redisService.setIfAbsent(redisKey, 0, NoRulesEnums.DateFormat.yyMMdd.getDays(), TimeUnit.DAYS);
Long no = redisService.increment(redisKey);
consigneeName = consigneeName + String.format("%0" + 5 + "d", no);
}else {
consigneeName += LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyMMdd"));
String redisKey = redisService.genKey(new String[]{NoRules.class.getSimpleName()}, consigneeName);
redisService.setIfAbsent(redisKey, 0, NoRulesEnums.DateFormat.yyMMdd.getDays(), TimeUnit.DAYS);
Long no = redisService.increment(redisKey);
consigneeName = consigneeName + String.format("%0" + 5 + "d", no);
}
//托盘信息
List<CrossdockPalletLabelNew> labelList = Lists.newArrayList();
CrossdockPalletLabelNew palletLabel = new CrossdockPalletLabelNew().setCustomer(customer.getCode())
.setPrintDate(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd")))
.setContainerNo(StringUtils.right(crossdock.getContainerNo(), 5))//取后5位
.setTotalAmount(crossdock.getTotalAmount().stripTrailingZeros().toPlainString())// 转运单总箱数
.setWarehouse(consignee.getName())// 收件人名称
.setPieces(request.getPieces().stripTrailingZeros().toPlainString())
.setBarcode(consigneeName)
.setPalletNO(consigneeName);
labelList.add(palletLabel);
//保存crossdock_plan_pallet
BigDecimal palletCount = planPalletService.countByFieldValue(consigneeName, CrossdockPlanPallet::getPalletNo);
if (palletCount.compareTo(BigDecimal.ZERO) <= 0) {
CrossdockPlanPallet pallet = new CrossdockPlanPallet();
pallet.setPalletNo(consigneeName).setOrderId(crossdock.getId()).setAmount(request.getPieces());
if (ObjectUtils.isNotEmpty(plan) && StringUtils.isNotBlank(plan.getId())){
pallet.setPlanId(plan.getId());
}
planPalletService.save(pallet);
}else {
throw new ApiException(ResultCode.FORBIDDEN,"msg:the_pallet_code_already_exists");
}
//保存crossdock_plan_pda
BigDecimal pdaCount = planPdaService.countByFieldValue(consigneeName, CrossdockPlanPda::getPalletNo);
if (pdaCount.compareTo(BigDecimal.ZERO) <= 0) {
CrossdockPlanPda pda = new CrossdockPlanPda();
pda.setPalletNo(consigneeName).setOrderNo(crossdock.getOrderNo()).setStatus(CrossdockEnums.PlanPdaStatus.INBOUND.name());
if (ObjectUtils.isNotEmpty(plan) && StringUtils.isNotBlank(plan.getPlanNo())){
pda.setPlanNo(plan.getPlanNo());
}
if(request.getIsTemp()){
pda.setSourcePalletNo(PrintEnums.sourcePalletNo.STORAGE.name());
}else {
pda.setSourcePalletNo(PrintEnums.sourcePalletNo.PLAN.name());
}
planPdaService.save(pda);
}else {
throw new ApiException(ResultCode.FORBIDDEN,"msg:the_pallet_code_already_exists");
}
//保存托盘打印日志
PalletPrintLogCreateRequest log = new PalletPrintLogCreateRequest().setOrderId(crossdock.getId())
.setPalletNo(consigneeName)
.setIsCustomize(request.getIsCustomize())
.setPieces(request.getPieces());
if (ObjectUtils.isNotEmpty(plan) && StringUtils.isNotBlank(plan.getId())){
log.setPlanId(plan.getId());
}
palletPrintLogService.createPalletPrintLog(log);
printPalletLabel(labelList, response.getOutputStream());
}
public void printPalletLabel(List<CrossdockPalletLabelNew> labelList, OutputStream outputStream) throws Exception {
Document doc = new Document();
PdfCopy copy = new PdfCopy(doc, outputStream);
doc.open();
BaseFont bf = BaseFont.createFont(TEMPLATE_FONT, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
for (CrossdockPalletLabelNew label : labelList) {
for(int i = 0; i < NUM_TO_PRINT; i++) {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
PdfStamper stamper = new PdfStamper(new PdfReader(PALLET_TEMPLATE), bos);
Map<String, Object> fieldMap = BeanMap.create(label);
AcroFields fields = stamper.getAcroFields();
fields.addSubstitutionFont(bf);
for (String key : fieldMap.keySet()) {
if (key.equals(BARCODE)) {
createBarcode(stamper.getOverContent(1), label.getBarcode(), fields.getFieldPositions(BARCODE).get(0).position);
} else {
fields.setField(key, Objects.toString(fieldMap.get(key), StringPool.EMPTY));
}
}
stamper.setFormFlattening(true);
stamper.close();
copy.addPage(copy.getImportedPage(new PdfReader(bos.toByteArray()), 1));
}
}
doc.close();
}
private final String TEMPLATE_FONT = "template/font/Alibaba-PuHuiTi-Medium.ttf";
private final String PALLET_TEMPLATE = "template/pallet.pdf";
private final int NUM_TO_PRINT = 2;
生成条形码
private void createBarcode(PdfContentByte cb, String barcode, Rectangle position) throws DocumentException {
Barcode128 barcode128 = new Barcode128();
barcode128.setCode(barcode);
barcode128.setX(1.7F);
barcode128.setBarHeight(position.getHeight());
Image image128 = barcode128.createImageWithBarcode(cb, null, null);
image128.scaleToFit(position.getWidth(), position.getHeight());
image128.setAbsolutePosition(position.getLeft() + (position.getWidth() - image128.getScaledWidth()) / 2,
position.getBottom() + (position.getHeight() - image128.getScaledHeight()) / 2);
cb.addImage(image128);
}
三,效果图
后面还会写复杂表格的填充并生成pdf