根据项目需求,需要用到一个功能,根据页面参数需要动态的生成一个world,并将world生成两份PDF文件,一份正式文件,一份临时的电子文件(带有二维码,扫描可以下载正式文件的电子版本)。同时上传到文件存储服务器minio上,下面介绍具体的实现步骤
1、首先准备一个world模板,新建一个world如下图所示
在需要动态填入数据的地方采用字母代替(此处注意,字母需要大写),用于占位操作。
2、编辑代码,项目接口,我采用的是一般的是SpringBoot项目结构,具体不多述,下面贴出关键代码:①根据接口获取到的参数,来开始命名最后要生成的pdf文件
scXwblPdfRequest 是接口传来的实体形的参数
- //生成文件名
- String pdfName = FileUpload.aliyungenFileNameNew("文档名_"+scXwblPdfRequest.getWorkUnit()+"_"+scXwblPdfRequest.getName());
- String fileName = pdfName + "_2.pdf";
- String fileNameZswj = pdfName+".pdf";
②准备文件
- String pdfUrl = fwurl +bucketName+Constants.SPRIT+ fileName;
- String pdfUrlZswj = fwurl +bucketName+Constants.SPRIT+ fileNameZswj;
- //获取本地准备的world模板
- String mblj = "file/xwbl_1.doc";
- Map
textMap = createXwblTextMap(scXwblPdfRequest ); - //设置pdf的文件地址(含二维码)
- String pdfUrl = fwurl +bucketName+Constants.SPRIT+ fileName;
- //设置pdf的正式文件地址(不含二维码)
- String pdfUrlZswj = fwurl +bucketName+Constants.SPRIT+ fileNameZswj;
方法说明:createXwblTextMap是将接口传来的实体参数,进行处理,以map形式处理好
- //构造textMap
- public Map createXwblTextMap(ScXwblPdfRequest xwblPdfRequest){
- Map
textMap = new HashMap<>(); - //开始时间
- textMap.put("STIME",String.valueOf(xwblPdfRequest.getStartTime()));
- //结束时间
- textMap.put("ETIME",String.valueOf(xwblPdfRequest.getEndTime()));
- //地点
- textMap.put("XWADRESS",xwblPdfRequest.getXwadress());
- //姓名
- textMap.put("NAME",xwblPdfRequest.getName());
- //性别
- textMap.put("SEX",xwblPdfRequest.getSex());
- return textMap;
- }
3、文件的其他信息处理,uploadforXwblUrl:是处理world完成后生成含有二维码的pdf文件,XwblzswjUrl :是处理world完成后生成不含有二维码的pdf文件
- //保存两个pdf,一个含二维码的临时文件,一个正式文件
- //加了二维码,用于扫码下载 (pdfUrlZswj 用于给二维码下载地址)
- textMap.put("EWMTIPS","扫描二维码查看、下载正式文件");
- //不带二维码的地址
- String withoutEwmUrl = pdfUrlZswj;
- String uploadforXwblUrl = xwblcs(bucketName,textMap , pdfUrl , fileName , true , mblj , withoutEwmUrl );
- //没有二维码
- textMap.put("EWMTIPS","");
- String XwblzswjUrl = xwblcs(bucketName,textMap , pdfUrlZswj , fileNameZswj , false , mblj ,"");
- result.put("uploadforXwblUrl",uploadforXwblUrl);
- result.put("XwblzswjUrl", XwblzswjUrl);
方法说明:xwblcs作用:主要用于生成PDF文件
- //生成PDF文件
- public String xwblcs(String bucketName,Map
textMap , String pdfUrl ,String fileName , boolean ewm , String mbwj ,String withoutEwmUrl ) { - try{
- MinioUtils minio = new MinioUtils();
- //读取doc模板文件
- ClassPathResource classPathResource = new ClassPathResource(mbwj);
- Document doc = new Document(classPathResource.getInputStream());
- DocumentBuilder builder = new DocumentBuilder(doc);
- //关闭文件流
- classPathResource.getInputStream().close();
- //向文档中插入文字
- AsposeUtil.docTextReplace(doc , textMap);
- //插入二维码
- if(ewm){
- AsposeUtil.docEwmReplace(builder ,withoutEwmUrl);
- }
- OutputStream outputStreamPdf= new ByteArrayOutputStream(1024);
- doc.save(outputStreamPdf, SaveFormat.PDF);
- ByteArrayOutputStream baosPdf = (ByteArrayOutputStream) outputStreamPdf ;
- ByteArrayInputStream inputStreamPdf = new
- ByteArrayInputStream(baosPdf.toByteArray());
- /**生成好的PDF文件上传到minio**/
- minio.putObject(bucketName,fileName,inputStreamPdf,"application/pdf");
- //关闭流
- baosPdf.close();
- inputStreamPdf.close();
- outputStreamPdf.close();
- /**生成的刚上传的PDF文件返文件路径**/
- return pdfUrl;
- }catch (Exception e){
- log.error(e.toString());
- throw new BussinessException(BizExceptionEnum.PDF_ERROR);
- }
- }
AsposeUtil:工具类,用于处理文字、图片插入插入文档,贴代码
- @Slf4j
- public class AsposeUtil {
- /**
- * word转pdf
- */
- public static void docToPdf(String intPath, String outPath) throws Exception {
- Document doc = new Document(intPath);
- FileOutputStream os = null;
- //新建一个pdf文档
- //File file = new File(outPath);
- //os = new FileOutputStream(file);
- //保存为pdf文件,saveFormat取的是words包下的,值为:40
- doc.save(outPath);
- //os.close();
- }
-
- public static void docTextReplace(Document doc, Map
textMap) throws Exception { - Range range = doc.getRange();
- for (Map.Entry
entry : textMap.entrySet()) { - range.replace(entry.getKey(), entry.getValue(), true, false);
- }
- }
-
- public static void docEwmReplace(DocumentBuilder builder , String pdfUrl) throws Exception {
- //读取用于放在二维码中间的图片
- ClassPathResource classPathResource1 = new ClassPathResource("file/ewmLogo.jpg");
- OutputStream outputStream = new ByteArrayOutputStream(1024);
- QRCodeUtil.encode(pdfUrl, classPathResource1.getInputStream(),outputStream , true);
- classPathResource1.getInputStream().close();
- ByteArrayOutputStream baos = (ByteArrayOutputStream) outputStream ;
- ByteArrayInputStream inputStream = new ByteArrayInputStream(baos.toByteArray());
- //插入二维码
- builder.moveToBookmark("EWM");
- builder.insertImage(inputStream , 150 , 150);
- outputStream.close();
- baos.close();
- inputStream.close();
- inputStream.close();
- }
-
- }
这里需要注意的是。在这个工具类中,有向world中插入图片的操作,builder.moveToBookmark("EWM");,这里插入进去的图片,不是用占位符去对应的,而是在world模板中需要插入一个名为“EWM”的书签,
最后流程介绍到此结束。最后用接口工具调用该接口,会返回两个地址,一个带二维码。一个不带二维码
最后访问minio的地址获取到两个pdf文件。同时手机或者pad,扫描带有二维码的pdf上的二维码,也能下载不带二维码,用于打印的文档