#使用POI实现word模板导出
笔者的word模板没有存在的OSS中,因为模板不多,故我是在Spring boot项目中的resources中创建了一个专门用于存放word模板的文件夹

首先创建一个word模板
通过ctrl+F9编辑域空间 格式为${name}

InputStream in = null;
        FileOutputStream out =null;
        String filename ="";
        /*
		wordTemplate/ 是resources下创建的模板文件夹
*/
//读取模板
         ClassPathResource classPathResource = new ClassPathResource("wordTemplate/" + "分析模板.docx");
         String path = classPathResource.getPath();
         in = this.getClass().getClassLoader().getResourceAsStream(path);
//获取context 
      IXDocReport report = XDocReportRegistry.getRegistry().loadReport(in, TemplateEngineKind.Freemarker);
            IContext context = report.createContext();
            FieldsMetadata fm = report.createFieldsMetadata();
	
	//获取图片
	     fm.addFieldAsImage("one");
	     //这里我是获取的阿里OSS的线上图片
	     //不想使用线上的可以直接获取到路径上的图片即可
            InputStream one= Downimage.steamToFile(lineImgUrl);
            context.put("one",one);
    //获取列表
		fm.load("line",ImpactAnalysis.class,true);
		  List<ImpactAnalysis> analysisList = new ArrayList<>();
            if (null!=mapNewLineRoad){
                String repeatLine = mapNewLineRoad.getRepeatLine();
                if(null!=repeatLine){
                    String[] split = repeatLine.split(";");
                    for (int i = 0; i < split.length; i++) {
                        ImpactAnalysis analysis = new ImpactAnalysis();
                        analysis.setAffectedLine(split[i]);
                        analysisList.add(analysis);
                    }
                }

            }
            context.put("line",analysisList);
		//这部分代码既是生成到当前项目的上一级工作空间
			//这里是获取到当前项目的根
	        String property = System.getProperty("user.dir");
	        //当前项目根的上一级
            property = property.substring(0, property.lastIndexOf(File.separator));
            log.info("获取当前项目的相对路径,改路径为",property);
            filename =property+"/新增路线分析表"+format+".docx";
            out = new FileOutputStream(new File(filename));
            report.process(context, out);
//------------------上面这部分代码则可以生成在一份word----------------------
//------------------将word发送到浏览器下面这部分----------------------------
           /* response.setCharacterEncoding("utf-8");
            response.setContentType("application/msword");
            response.setHeader("Content-Disposition", "attachment;filename="
                    .concat(String.valueOf(URLEncoder.encode(fileName, "UTF-8"))));
            report.process(context, response.getOutputStream());
            */
      one.close();
        }catch (IOException e) {
            log.error("读取Word模板异常",e);
        } catch (XDocReportException e) {
            log.error("word模板生成失败",e);
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            if(in!=null){
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(out!=null){
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            //不需要将word转换成PDF这里可不要
            if (filename!=null){
                try{
                    Word2PdfAsposeUtil.pdf(filename,response,0);
                }catch (Exception e){
                    e.getMessage();
                }
            }

        }
public static BufferedInputStream steamToFile(String destUrl) {
        FileOutputStream fos = null;
        BufferedInputStream bis = null;
        HttpURLConnection httpUrl = null;
        URL url = null;
        int BUFFER_SIZE = 1024;
        byte[] buf = new byte[BUFFER_SIZE];
        int size = 0;
        String dir="E://";
        String filename = String.valueOf(System.currentTimeMillis())+".png";
        try {
            url = new URL(destUrl);
            httpUrl = (HttpURLConnection) url.openConnection();
            httpUrl.connect();
            bis = new BufferedInputStream(httpUrl.getInputStream());
        } catch (IOException e) {
        } catch (ClassCastException e) {
        } finally {
            try {
                fos.close();
                bis.close();
                httpUrl.disconnect();
            } catch (IOException e) {
            } catch (NullPointerException e) {
            }
        }
        return bis;
    }
@Data
public class ImpactAnalysis {

    //影响线路
    private String affectedLine;


    //重复系数
    private String repeatabilityFactor;


    //影响客流预测(人次/天)
    private String people;

}

#这部分是将word转换成PDF的代码
这里主要是用了aspose
这里是将jar包下载下来,然后导入到项目中,如何导入可以百度一下
这里需要注意一点就是,本地导入的jar包,发布在测试服可能会出现读取不到这个jar包的情况。倘若出现这种情况则需要在pom文件中加入这个

<build>
		<finalName>finalName</finalName>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
				<configuration>
					<fork>true</fork> 
					<!-- 如果没有该配置,devtools不会生效 -->
					<!--设置为true,以便把本地的system的jar也包括进来-->
					<includeSystemScope>true</includeSystemScope>
				</configuration>
			</plugin>
		</plugins>
	</build>

jar包加入到lib中,需要maven导入进来

<dependency>
			<groupId>com.aspose.words</groupId>
			<artifactId>aspose-words</artifactId>
			<version>words-15.8.0-jdk16</version>
			<scope>system</scope>
			<systemPath>${project.basedir}/src/main/resources/lib/aspose-words-18.6-jdk16-crack.jar</systemPath>
		</dependency>

#最后这里存在一个问题,就是导出预览的时候,左上角的标题是存放在Google的临时空间的,这里找了一个pdfbox来修正
##这是maven坐标

<dependency>
			<groupId>org.apache.pdfbox</groupId>
			<artifactId>pdfbox</artifactId>
			<version>1.8.8</version>
		</dependency>
		<dependency>
			<groupId>org.apache.pdfbox</groupId>
			<artifactId>fontbox</artifactId>
			<version>1.8.8</version>
		</dependency>
public static boolean getLicense() {
        boolean result = false;
        try {

            ClassPathResource classPathResource = new ClassPathResource("wordTemplate/" + "license.xml");
            String path = classPathResource.getPath();
            InputStream is = Word2PdfAsposeUtil.class.getClassLoader().getResourceAsStream(path);
            License aposeLic = new License();
            aposeLic.setLicense(is);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    public static String doc2pdf(String inPath, String outPath) {
        if (!getLicense()) { // 验证License 若不验证则转化出的pdf文档会有水印产生
            return null;
        }
        FileOutputStream os = null;
        try {
            String path = outPath.substring(0, outPath.lastIndexOf(File.separator));
            log.info("第二次获取当前项目的相对路径,改路径为",path);
            long old = System.currentTimeMillis();
            File file = new File(path); // 新建一个空白pdf文档
            if (!file.exists()) {
                file.mkdirs();
            }
            file = new File(outPath);
            os = new FileOutputStream(file);

            Document doc = new Document(inPath); // Address是将要被转化的word文档
            doc.save(os, SaveFormat.PDF);// 全面支持DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF,
            // EPUB, XPS, SWF 相互转换
            long now = System.currentTimeMillis();
            os.close();
            log.info("pdf转换成功,共耗时:" + ((now - old) / 1000.0) + "秒"); // 转化用时

        } catch (Exception e) {
            e.printStackTrace();

        }finally {
            if (os != null) {
                try {
                    os.flush();
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return outPath;
    }



    public static void pdf(String url, HttpServletResponse response,Integer number) throws Exception {
        if (StringUtils.isBlank(url)) {
            return;
        }
        File file = null;
        String property = System.getProperty("user.dir");
        System.out.println("第二次获取到的相对路径:"+property);
        // 文件后缀
        String suffix = url.substring(url.lastIndexOf(".") + 1);
        if ("doc".equals(suffix) || "docx".equals(suffix)) {
            file = new File(Word2PdfAsposeUtil.doc2pdf(url, property + "线路新增审核" + ".pdf"));
        }
        try {

            InputStream stream = new FileInputStream(file);
            ServletOutputStream out = response.getOutputStream();
            byte buff[] = new byte[1024];
            int length = 0;
            //开始写入文件
            while ((length = stream.read(buff)) > 0) {
                out.write(buff, 0, length);
            }

            /*
            * 这里存在一个问题,就是导出到浏览器预览,名称没有了
            *
            * */
           // response.setContentType("application/msword");
           /* log.info("----------------filename--------------"+file.getName());
            String fileName = new String(file.getName().getBytes("UTF-8"), "ISO8859-1");
            log.info("----------------fileName--------------"+fileName);
            response.reset();
            response.setContentType("application/pdf;charset=UTF-8");
            response.setCharacterEncoding("UTF-8");
            response.addHeader("Content-Disposition", "attachment;filename=" + file.getName());
            response.addHeader("Content-Length", "" + file.length());
            if (number==0){
                response.setHeader("Content-Disposition", "attachment;filename="+fileName
                        .concat(String.valueOf(URLEncoder.encode("线路新增审核", "UTF-8"))));
            }
            if (number==1){
                response.setHeader("Content-Disposition", "attachment;filename="+fileName
                        .concat(String.valueOf(URLEncoder.encode("线路调整审核", "UTF-8"))));
            }
            if (number==2){
                response.setHeader("Content-Disposition", "attachment;filename="+fileName
                        .concat(String.valueOf(URLEncoder.encode("线路撤销审核", "UTF-8"))));
            }*/
         /*   Thread.sleep(500);
            //这里采取在读一次硬盘中的文件,在将字节流返回
            //获取到PDF保存路径
            String path =file.getPath();
            File pdfFile = new File(path);
            InputStream fis = new BufferedInputStream(new FileInputStream(pdfFile));
            byte[] buffer = new byte[fis.available()];
            fis.read(buffer);
            fis.close();
            response.reset();
            response.setContentType("application/pdf;charset=UTF-8");
            response.setCharacterEncoding("UTF-8");
            response.addHeader("Content-Disposition", "attachment;filename=" + new String(file.getName().getBytes()));
            response.addHeader("Content-Length", "" + file.length());
            OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
            toClient.write(buffer);
            toClient.flush();
            toClient.close();*/

            //使用PDFdocument设置
            File pdffile = new File(file.getPath());
            try (
                    OutputStream outputStream = response.getOutputStream();
                 //加载pdf附件到PDF流中
                    PDDocument document = PDDocument.load(new FileInputStream(file))) {
                    response.setCharacterEncoding("UTF-8");
                    String showName =  pdffile.getName();
                    //showName = URLEncoder.encode(showName, "UTF-8");
                    response.setHeader("Content-Disposition", "attachment;filename="+showName.concat(String.valueOf(URLEncoder.encode(showName, "UTF-8"))));
                    //response.setHeader("Content-Disposition", "inline;fileName=" + new String(showName.getBytes()) + ";fileName*=UTF-8''" + new String(showName.getBytes()));
                    //从PDF流中获得PDF文档属性对象
                    PDDocumentInformation info = document.getDocumentInformation();
                    //设置PDF文档属性对象的文件名称(最重要的环节)
                    info.setTitle(showName);
                    document.setDocumentInformation(info);
                    //修改完直接输出到响应体中
                    document.save(outputStream);
            } catch (Exception e) {
                log.error( e.getMessage());
            }

            stream.close();
            out.close();
            out.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

#总结一下,这真的是峰回路转,主要是一开始需求不明确,开始只是导出word,结果后面要求把word转换成PDF,没办法aspose的document好像只能读取文件路径而不是流文件,就只能通过读取生产好的word进行转换,又因为这样转换到前端的名字不对,最后只能生产出来PDF不发给前端,保存在服务器中再次读取,重新设置好名称什么的发给前端。