pdf导出,做一记录
导出样式:
一。工具类
import com.itextpdf.text.pdf.BaseFont; import freemarker.template.Template; import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Configuration; import org.springframework.ui.freemarker.FreeMarkerTemplateUtils; import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer; import org.xhtmlrenderer.pdf.ITextRenderer; import javax.annotation.Resource; import javax.servlet.http.HttpServletResponse; import java.io.*; import java.net.URLEncoder; import java.util.Locale; @Slf4j @Configuration public class PdfUtils { @Resource private FreeMarkerConfigurer freeMarkerConfigurer; public void createPdf(Object object, String templatesName, HttpServletResponse response,String fileName) throws Exception { Template template = freeMarkerConfigurer.getConfiguration().getTemplate(templatesName); String html = FreeMarkerTemplateUtils.processTemplateIntoString(template, object); ByteArrayOutputStream baos = new ByteArrayOutputStream(); ITextRenderer renderer = new ITextRenderer(); renderer.getFontResolver().addFont("/templates/font/simsun.ttc", "Identity-H", false);//位置 renderer.setDocumentFromString(html); renderer.getSharedContext().setBaseURL("images/"); renderer.layout(); renderer.createPDF(baos, false); renderer.finishPDF(); OutputStream out=response.getOutputStream(); try { response.setCharacterEncoding("UTF-8"); response.setHeader("content-Type", "application/force-download"); response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName + ".pdf" , "UTF-8")); baos.writeTo(out); } catch (Exception e) { throw new IOException(e.getMessage()); }finally { baos.flush(); baos.close(); out.flush(); out.close(); } } }
二.模板样式
<!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"> @page{ /*size: 535px 600px;*/ margin: 0; } body {font-family: SimSun;} /*.mybody h1 {font-size: 24px;text-align: center;line-height: 30px;padding: 20px 0;padding-top: 30px;}*/ .mybody h3 {font-size: 18px;text-align: center;} /*.content_class p {display: block;margin-block-start: 1em;margin-block-end: 1em;margin-inline-start: 0px;margin-inline-end: 0px;}*/ /*.content_class{box-shadow:none;line-height:30px;margin:-30px auto;height: auto !important;padding: 0px 75px 100px 75px !important;}*/ /*.Gzimg{ position:absolute;left: 400px;top:-35px;width: 140px;height: 140px;}*/ /*.table tb1{ border-collapse:collapse; margin:0px auto; }*/ /*.table tr{ width:700px; text-align:center; border:1pxsolid #000000; }*/ /*.table td{ border:1pxsolid; text-align:center; vertical-align:middle; }*/ /*.table th{ margin:0auto; text-align:center; border:1pxsolid; }*/ table{width:99%;} td{font-size: 14px;font-weight: 600} .td_class{word-break: keep-all;white-space:nowrap;} </style> </head> <body style="padding: 0px;margin-top:0px;width: 99%;"> <table style="margin: 0"> <tr> <td style="word-break: keep-all;margin: 0;text-align: center;font-size: 20px;"> <nobr>采购计划</nobr> </td> </tr> </table> <table class="table_class" style="margin-top:0px"> <tr> <td colspan="4" style="word-break: keep-all;"><nobr>订单编号:${st.purchId}</nobr></td> <td colspan="3" style="word-break: keep-all;"><nobr>创建人:${st.buyerName}</nobr></td> <td colspan="3" style="word-break: keep-all;"><nobr>入库时间:${st.billlingTime}</nobr></td> </tr> </table> <table border="1" cellspacing="0" cellpadding="0" > <thead> <tr> <th style="text-align: center;width: 5%;">序号</th> <th style="text-align: center;width: 10%;">编号</th> <th style="text-align: center;width: 15%;">产品名称</th> <th style="text-align: center;width: 12%;">规格</th> <th style="text-align: center;width: 7%;">单位</th> <th style="text-align: center;width: 8%;">数量</th> <th style="text-align: center;width: 8%;">进价</th> <th style="text-align: center;width: 8%;">小计</th> <th style="text-align: center;width: 15%;">供应商</th> <th style="text-align: center;width: 6%;">备注</th> </tr> </thead> <tbody> <#list st.list as list> <tr> <td style="text-align: center;word-wrap:break-word;word-break:break-all;;font-size: 14px;font-weight: 800;line-height:40px;">${list_index+1}</td> <td style="text-align: center;word-wrap:break-word;word-break:break-all;;font-size: 14px;font-weight: 800;line-height:40px;">${list.goodsIdStr}</td> <td style="text-align: center;word-wrap:break-word;word-break:break-all;font-size: 14px;font-weight: 800">${list.commonName}</td> <#if (list.specificationsModel)??> <td style="text-align: center;word-wrap:break-word;word-break:break-all;">${list.specificationsModel}</td> <#else> <td style="text-align: center;word-wrap:break-word;word-break:break-all;"></td> </#if> <td style="text-align: center;word-wrap:break-word;word-break:break-all;">${list.unit}</td> <td style="text-align: center;word-wrap:break-word;word-break:break-all;">${list.number}</td> <td style="text-align: center;word-wrap:break-word;word-break:break-all;"><#if (list.taxPrice)??>${list.taxPrice}<#else > 0</#if></td> <td style="text-align: center;word-wrap:break-word;word-break:break-all;"><#if (list.taxPrice)??>${list.taxTotalPrice}<#else > 0.0</#if></td> <td style="text-align: center;word-wrap:break-word;word-break:break-all;">${list.supplierName}</td> <td style="text-align: center;word-wrap:break-word;word-break:break-all;"><#if (list.remark)??>${list.remark}</#if></td> </tr> </#list> <tr> <td colspan="6" style="border:none;word-break: keep-all;" align="left"> 总金额大写:${st.convertUpMoney} </td> <td colspan="4" style="border:none;word-break: keep-all;" align="center"> 总金额:${st.totalPrice} </td> </tr> </tbody> </table> <table style="text-align: left;width: 98%;"> <tr> <h3 style="overflow: hidden"> <div style="border-radius: 3px;height: 25px;width: 4px;background: royalblue;float:left;margin-right: 6px"></div> <font size="5" color="black">审批记录</font> </h3> </tr> <#list st.listRe as re> <tr> <td style="text-align: left;width: 38%;"> <#if re_index==0> <font style="font-size: 16px;color: royalblue">#{re_index+1} 创建计划</font> <#else > <font style="font-size: 16px;color: royalblue"> #{re_index+1}<#if re.type==1> 通过 <#else>打回</#if></font> </#if> </td> <td style="text-align: left;width: 60%;"> <#if re_index==0> <font >创建人:<#if (re.userName)??>${re.userName}</#if></font><br/> <#else > <font >审批人:<#if (re.userName)??>${re.userName}</#if></font><br/> </#if> <font ><#if (re.createTimeStr)??>${re.createTimeStr}</#if></font> </td> </tr> </#list> </table> <div class="mybody"> </div> </body> </html>
三。控制层
@Autowired
private PdfUtils pdfUtils;
@RequestMapping("/exportPurchasePdfList") @ResponseBody public void exportPurchasePdfList(HttpServletResponse response, @LoginUser(isFull = true) SysUser sysUser, @RequestBody ExportPdf exportPdf) throws Exception{ log.info("导出采购计划dpf入参:sysUser:{}, exportPdf:{}", sysUser, exportPdf); PurchaseOrderInfo entryDetailDTO = ordDetailInfoService.exportPurchasePdfList(sysUser, exportPdf); if(entryDetailDTO!=null&&entryDetailDTO.getList()!=null&&entryDetailDTO.getList().size()>0) {
// 三联打印 // List<PurchaseOrderInfo> storageS = new ArrayList<>(); // int count = (entryDetailDTO.getList().size() + 5 - 1) / 5; // for (int i = 0; i < count; i++) { // PurchaseOrderInfo info = new PurchaseOrderInfo(); // BeanUtils.copyProperties(entryDetailDTO, info); // info.setList(null); // List<PurchaseOrdDetailInfo> listG = new ArrayList<>(); // BigDecimal price = new BigDecimal(0.0); // int x = i * 5; // int y = (i + 1) * 5 - 1; // while (x <= y && x < entryDetailDTO.getList().size()) { // PurchaseOrdDetailInfo st = entryDetailDTO.getList().get(x); // if (StringUtil.isNotBlank(st.getCommonName())&&st.getCommonName().length()>18) { // st.setCommonName(st.getCommonName().substring(0, 17)); // } // if (StringUtil.isNotBlank(st.getProductionEnterprise())&&st.getProductionEnterprise().length()>18) { // st.setProductionEnterprise(st.getProductionEnterprise().substring(0, 17)); // } // price = price.add(st.getTaxTotalPrice()); // listG.add(st); // x++; // } // info.setConvertUpMoney(ConvertUpMoneyUtil.convert(price.doubleValue())); // info.setTotalPrice(price); // info.setList(listG); // storageS.add(info); // } Map<String, Object> map = new HashMap<>(); map.put("st", entryDetailDTO); pdfUtils.createPdf(map,"purchase_detail.ftl",response,"采购计划单导出"); }
service:
@Override public PurchaseOrderInfo exportPurchasePdfList(SysUser sysUser, ExportPdf exportPdf) { if (StringUtil.isBlank(exportPdf.getEntryDetailId())) { throw new ValidateException(StaticCode.EXCEPTION_RESPONSE_CODE.EXCEPTION_RESPONSE_CODE_402, "缺少必要参数!"); } PurchaseOrderInfo info=purchaseOrderInfoMapper.findOrderByPurchId(exportPdf.getEntryDetailId()); SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); if(info!=null){ if(info.getState().equals(PurchaseCode.ORDER_UPD)){ throw new ValidateException(StaticCode.EXCEPTION_RESPONSE_CODE.EXCEPTION_RESPONSE_CODE_402, "当前订单未完成,不能导出!"); }else { List<PurchaseOrdDetailInfo> list = purchaseOrdDetailInfoMapper.queryGoodsDetailsBypurchId(info.getPurchId()); if (list != null && list.size() > 0) { info.setList(list); } } List<PurchaseRecord> listre=purchaseRecordMapper.selectList(new QueryWrapper<PurchaseRecord>().eq("purch_id",info.getPurchOldId()).orderByAsc("create_time")); if(listre!=null&&listre.size()>0) { for(PurchaseRecord re:listre){ re.setCreateTimeStr(format.format(re.getCreateTime())); } info.setListRe(listre); } } SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd"); info.setBilllingTime(f.format(info.getCreateTime())); if(info.getList()==null||info.getList().size()<=0){ throw new ValidateException(StaticCode.EXCEPTION_RESPONSE_CODE.EXCEPTION_RESPONSE_CODE_402, "当前订单下无商品!"); } BigDecimal price = new BigDecimal(0.0); for (PurchaseOrdDetailInfo goodsInfo:info.getList()){ if(goodsInfo.getTaxTotalPrice()==null){ price = price.add(new BigDecimal(0.0)); }else{ price = price.add(goodsInfo.getTaxTotalPrice()); } if (goodsInfo.getProductionEnterprise() == null) { goodsInfo.setProductionEnterprise(" "); } goodsInfo.setGoodsIdStr(goodsInfo.getGoodsId().toString()); } info.setConvertUpMoney(ConvertUpMoneyUtil.convert(price.doubleValue())); info.setTotalPrice(price); return info; }
实体类
@Data @EqualsAndHashCode(callSuper = false) @Accessors(chain = true) @TableName("purchase_order_info") @ApiModel(value="PurchaseOrderInfo对象", description="采购单") public class PurchaseOrderInfo extends Model<PurchaseOrderInfo> implements Serializable { private static final long serialVersionUID = 1L; @ApiModelProperty(value = "采购单id") @TableId(value = "purch_id",type = IdType.INPUT ) private String purchId; @ApiModelProperty(value = "采购员id") @TableField("buyer_id") @NotNull( message = "采购员不能为空") private Integer buyerId; @ApiModelProperty(value = "采购员姓名") @TableField("buyer_name") private String buyerName; @ApiModelProperty(value = "结束时间") @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd") @DateTimeFormat(pattern="yyyy-MM-dd") private Date updateTime; @ApiModelProperty(value = "状态") private Integer state; @ApiModelProperty(value = "备注") private String remark; @ApiModelProperty(value = "供应商id") @TableField("supplier_id") private Integer supplierId; @ApiModelProperty(value = "供应商名称") @TableField("supplier_name") private String supplierName; @ApiModelProperty(value = "门店编码") @TableField("clinic_code") private String clinicCode; @ApiModelProperty(value = "门店名称") @TableField("clinic_name") private String clinicName; private Date createTime; @TableField(exist = false) private List<PurchaseOrdDetailInfo> list; @TableField(exist = false) private String stateName; @ApiModelProperty(value = "开票时间") @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd") @DateTimeFormat(pattern="yyyy-MM-dd") private Date billingTime; @ApiModelProperty(value = "总费用") @JsonSerialize(using = BigDecimalSerialize.class) private BigDecimal totalPrice; @ApiModelProperty(value = "采购总数量") private Integer totalNum; private String goodsContent; @TableField(exist = false) private String orderState; private String purchaseState; @TableField(exist = false) private Integer storageNum; @TableField(exist = false) @JsonSerialize(using = BigDecimalSerialize.class) private BigDecimal storagePrice; @ApiModelProperty(value = "采购类别 1普通采购 2时空对接采购") private Integer classify=1; private Long approvalId; private String approvalName; @TableField(exist = false) private String parentCode; private Integer isUse; private Integer approveState; @TableField(exist = false) private String approveStateName; @TableField(exist = false) private String approveRemark; @TableField(exist = false) private String approveType; private String purchOldId; @TableField(exist = false) private List<PurchaseRecord> listRe; @TableField(updateStrategy = FieldStrategy.IGNORED) private String nextHandleIds; @TableField(updateStrategy = FieldStrategy.IGNORED) private String nextHandleNames; @TableField(exist = false) private List<ApprovalProcess> processList; @TableField(updateStrategy = FieldStrategy.IGNORED) private Integer nextProcessId; @TableField(exist = false) private Integer step; @TableField(exist = false) @JsonFormat(locale="zh", timezone="GMT+8", pattern="yyyy-MM-dd") private String InvoicingTime;//创建时间 @TableField(exist = false) @JsonFormat(locale="zh", timezone="GMT+8", pattern="yyyy-MM-dd") private String billlingTime;//开票时间 @ApiModelProperty(value = "收货人id") @TableField("consignee_id") @NotNull( message = "收货人编码不能为空") private Integer consigneeId; @ApiModelProperty(value = "收货人姓名") @TableField("consignee_name") @NotNull( message = "收货人不能为空") private String consigneeName; @ApiModelProperty(value = "金额大写") @TableField(exist = false) private String convertUpMoney; private String repulse; @TableField(exist = false) private String purchRemark; }