记一笔三联打印功能
结果:
工具类
import com.itextpdf.text.pdf.*; import freemarker.template.Configuration; import freemarker.template.Template; import lombok.extern.slf4j.Slf4j; import org.xhtmlrenderer.pdf.ITextRenderer; import java.io.File; import java.io.OutputStream; import java.io.StringWriter; import java.util.Locale; @Slf4j public class PdfUtils { //存放文件模板的地址 // private final static String TEMPLATE_BASE_PATH = "/opt/java_project/his-pro/static/template/"; private final static String TEMPLATE_BASE_PATH = "E:\\hx-com.his.base.api\\src\\main\\resources\\app\\static\\template\\"; //存放图片文件的地址(logo图片、机构公章等) private final static String IMG_BASE_PATH = "E:\\hx-com.his.base.api\\src\\main\\resources\\app\\static\\conf\\"; // private final static String IMG_BASE_PATH = "/opt/java_project/his-pro/static/conf/"; //存放字体资源文件的地址 private final static String FONT_BASE_PATH = "E:\\hx-com.his.base.api\\src\\main\\resources\\app\\static\\conf\\"; // private final static String FONT_BASE_PATH = "/opt/java_project/his-pro/static/conf/"; //默认字体资源文件([宋体][simsun.ttc]) private final static String DEFAULT_FONT = "simsun.ttc"; //指定编码 private final static String ENCODING = "UTF-8"; /** * 生成pdf * @param templateCode 模板 * @param data 传入到freemarker模板里的数据 * @param out 生成的pdf文件流 */ public static void createPDF(String templateCode, Object data, OutputStream out, String imgName) { try { String property = System.getProperty("user.dir"); // 创建一个FreeMarker实例, 负责管理FreeMarker模板的Configuration实例 Configuration cfg = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS); // 指定FreeMarker模板文件的位置 cfg.setDirectoryForTemplateLoading(new File(TEMPLATE_BASE_PATH)); ITextRenderer renderer = new ITextRenderer(); // 设置 css中 的字体样式(暂时仅支持宋体和黑体) renderer.getFontResolver().addFont(FONT_BASE_PATH + DEFAULT_FONT, BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); // 设置模板的编码格式 cfg.setEncoding(Locale.CHINA, ENCODING); // 获取模板文件 template.ftl Template template = cfg.getTemplate(templateCode, ENCODING); StringWriter writer = new StringWriter(); // 将数据输出到html中 template.process(data, writer); writer.flush(); String html = writer.toString(); // 把html代码传入渲染器中 renderer.setDocumentFromString(html); // 解决图片的相对路径问题 ##必须在设置document后再设置图片路径,不然不起作用 // 如果使用绝对路径依然有问题,可以在路径前面加"file:/" if(null != imgName && !"".equals(imgName)){ renderer.getSharedContext().setBaseURL(IMG_BASE_PATH + imgName); } renderer.layout(); renderer.createPDF(out, false); renderer.finishPDF(); out.flush(); out.close(); } catch (Exception e) { log.error("PDF导出异常", e); } } }
模板:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title></title> <meta http-equiv="content-type" content="text/html;charset=utf-8"/> <style type="text/css"> p{ line-height: 1.4; } @page{ size: 297mm 100mm; margin: 0; @top-center{ content: "页眉中间位置"; fone-family: SimSun; }; @bottom-center { content: "页脚中间位置"; fone-family: SimSun; }; @bottom-right{ content: "第" counter(page)"页 共" counter(pages) "页"; fone-family: SimSun; fone-size:15px; }; } #pagenumber:before{ content: counter(page); } #pagecount:before{ content: counter(pages); } h4 { margin: 0; padding: 0; } body {font-family: SimSun;} .mybody { padding: 0 20px; } .mybody h4 {font-size: 18px;text-align: center;} .mybody table {font-size: 16px; text-align: center; line-height: 26px;} table{ width: 100%; border-collapse: collapse; overflow: auto; } table tr th { font-weight: normal; } td { word-wrap: break-word; word-break: break-all; } </style> </head> <body> <#list priceAdjustmentFormList as priceAdjustmentForm> <div class="mybody"> <span style="display: inline-block; width: 100%; text-align:center;font-size: 20px;margin-top: 20px;">成本调价单</span> <table class="table_class"> <tr> <td colspan="3" style="word-break: keep-all;">单据编号: <#if (priceAdjustmentForm.documentNumber)??> ${priceAdjustmentForm.documentNumber} </#if> </td> <td colspan="3" style="word-break: keep-all;">开票员: <#if (priceAdjustmentForm.invoicer)??> ${priceAdjustmentForm.invoicer} </#if> </td> <td colspan="2" style="word-break: keep-all;">开票日期: <#if (priceAdjustmentForm.invoicerDate)??> ${priceAdjustmentForm.invoicerDate} </#if> </td> <#--<td style="word-break: keep-all;" class="td_class">第1页</td>--> <#--<td style="word-break: keep-all;" class="td_class">共1页</td>--> </tr> <#--<tr style="text-align: left;">--> <#--<td colspan="4"><nobr>出库门店名称:${outboundDTO.clinicName}</nobr></td>--> <#--<td colspan="4"><nobr>收货门店名称:${outboundDTO.applyClinicName}</nobr></td>--> <#--</tr>--> <#--<tr style="text-align: left;">--> <#--<td colspan="3"><nobr>出库单号:${outboundDTO.formNum}</nobr></td>--> <#--<td colspan="3"><nobr>关联单号:${outboundDTO.applyNum}</nobr></td>--> <#--<td colspan="2"><nobr>出库时间:${outboundDTO.allotTime}</nobr></td>--> <#--<td class="td_class"><nobr>第${outboundDTO_index+1}页</nobr></td>--> <#--<td class="td_class"><nobr>共${outboundDTOS?size}页</nobr></td>--> <#--</tr>--> </table> <table border="1" cellspacing="0" cellpadding="0" > <thead> <tr> <th width="6%">原编号</th> <th width="6%">商品编号</th> <th width="20%">产品名称</th> <th width="8%">规格</th> <th width="14%">生产厂商</th> <th width="8%">批号</th> <th width="8%">库存</th> <th width="8%">原成本进价</th> <th width="8%">新成本进价</th> <th width="8%">成本差价</th> <th width="8%">总差价</th> <#--<th width="6%">单位</th>--> <#--<th width="6%">数量</th>--> <#----> <#--<th width="8%">有效期至</th>--> </tr> </thead> <tbody> <#list priceAdjustmentForm.goodsList as list> <tr> <td style="text-align: center;"> <#if (list.oldCommodityCode)??> ${list.oldCommodityCode} </#if> </td> <td style="text-align: center;"> <#if (list.commodityCode)??> ${list.commodityCode} </#if> </td> <td style="text-align: center;"> <#if (list.commonName)??> ${list.commonName} </#if> </td> <td style="text-align: center;"> <#if (list.specificationsModel)??> ${list.specificationsModel} </#if> </td> <td style="text-align: center;"> <#if (list.productionEnterprise)??> ${list.productionEnterprise} </#if> </td> <td style="text-align: center;"> <#if (list.batchNumber)??> ${list.batchNumber} </#if> </td> <td style="text-align: center;"> <#if (list.availableNumber)??> ${list.availableNumber} </#if> </td> <td style="text-align: center;"> <#if (list.taxPrice)??> ${list.taxPrice} </#if> </td> <td style="text-align: center;"> <#if (list.newTaxPrice)??> ${list.newTaxPrice} </#if> </td> <td style="text-align: center;"> <#if (list.taxPriceDifference)??> ${list.taxPriceDifference} </#if> </td> <td style="text-align: center;"> <#if (list.sumDifference)??> ${list.sumDifference} </#if> </td> </tr> </#list> <#--<tr>--> <#--<td colspan="6" style="border:none;" align="left">--> <#--总金额大写:${outboundDTO.convertUpMoney}--> <#--</td>--> <#--<td colspan="5" style="border:none;" align="center">--> <#--总金额:${outboundDTO.price}--> <#--</td>--> <#--</tr>--> </tbody> </table> <table cellspacing="0" cellpadding="0" class="table_class"> <tr style="border:none"> <td colspan="2" style="border:none;">原总成本进价: <#if (priceAdjustmentForm.oldSumTax)??> ${priceAdjustmentForm.oldSumTax} </#if> </td> <td colspan="3" style="border:none;">新总成本进价: <#if (priceAdjustmentForm.sumInventory)??> ${priceAdjustmentForm.sumInventory} </#if> </td> <td colspan="3" style="border:none;">总成本差价: <#if (priceAdjustmentForm.sumDifference)??> ${priceAdjustmentForm.sumDifference} </#if> </td> <#--<td colspan="3" style="border:none;">出库人:${outboundDTO.allotMan}</td>--> </tr> </table> </div> </#list> </body> </html>
实体类
@Data public class PriceAdjustmentForm { private String documentNumber;//单据编号 private String Invoicer;//开票员 private String InvoicerDate;//开票日期 private List<InventoryModifyModel> goodsList; private String oldSumTax;//袁总成本进价 private String sumInventory; private String sumDifference; }
控制层
/** * 成本调价单三联打印 * @param response * @param sysUser * @param exportPdf * @throws Exception */ @PostMapping("exportPriceAdjustmentPrint") @ResponseBody public void exportPriceAdjustmentPrint(HttpServletResponse response, @LoginUser(isFull = true) SysUser sysUser, @RequestBody ExportPdf exportPdf) throws Exception{ PriceAdjustmentForm priceAdjustmentForm = exportService.exportPriceAdjustmentForm(sysUser, exportPdf); List<PriceAdjustmentForm> priceAdjustmentFormList = new ArrayList<>(); if (priceAdjustmentForm != null && CollectionUtils.isNotEmpty(priceAdjustmentForm.getGoodsList())) { int pageSize = 5; for (int i = 0; i < (int) Math.ceil((double) priceAdjustmentForm.getGoodsList().size() / pageSize); i++) { PriceAdjustmentForm info = new PriceAdjustmentForm(); BeanUtils.copyProperties(priceAdjustmentForm, info); info.setGoodsList(new ArrayList<>()); int k = i * pageSize; while (k < priceAdjustmentForm.getGoodsList().size() && k < (i+1) * pageSize) { info.getGoodsList().add(priceAdjustmentForm.getGoodsList().get(k)); k++; } priceAdjustmentFormList.add(info); } } Map<String, List<PriceAdjustmentForm>> map = new HashMap<>(); map.put("priceAdjustmentFormList", priceAdjustmentFormList); PdfUtils.createPDF("price_adjustmentT.ftl",map,response.getOutputStream(),null); }
逻辑层:(查询所需的东西,)
@Override public PriceAdjustmentForm exportPriceAdjustmentForm(SysUser sysUser, ExportPdf exportPdf) { if (StringUtil.isBlank(exportPdf.getAdjustmentPriceId())) { throw new ValidateException(StaticCode.EXCEPTION_RESPONSE_CODE.EXCEPTION_RESPONSE_CODE_402, "缺少必要参数!"); } PriceAdjustmentForm priceAdjustmentForm=new PriceAdjustmentForm(); InventoryModify modify= inventoryModifyDetailMapper.queryById(exportPdf.getAdjustmentPriceId()); List<InventoryModifyModel> list=inventoryModifyDetailMapper.findAllTaxPriceById(Integer.valueOf(exportPdf.getAdjustmentPriceId())); for (InventoryModifyModel model:list) { int i = model.getNewTaxPrice().compareTo(model.getTaxPrice()); if( i==-1){ model.setTaxPriceDifference("-"+model.getTaxPriceDifference()); model.setSumDifference("-"+model.getSumDifference()); } } InventoryModifyModel listsum=inventoryModifyDetailMapper.taxPriceByIdSum(Integer.valueOf(exportPdf.getAdjustmentPriceId())); priceAdjustmentForm.setDocumentNumber(exportPdf.getDocumentNumber()); priceAdjustmentForm.setInvoicer(modify.getCreateBy()); // LocalDateTime localDateTime=LocalDateTime.parse(dates,DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); String localDateTimeStr= modify.getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd ")); priceAdjustmentForm.setInvoicerDate(localDateTimeStr); priceAdjustmentForm.setGoodsList(list); priceAdjustmentForm.setOldSumTax(listsum.getOldSumTax()); priceAdjustmentForm.setSumInventory(listsum.getNewSumTax()); priceAdjustmentForm.setSumDifference(listsum.getDifference()); return priceAdjustmentForm; }