java中word,pdf 预览导出

该文章介绍了一个Java工具类,使用ApachePOI库处理Word文档中的文本替换,以及Aspose.Words库进行Word到PDF的转换。工具类包括方法用于根据模板生成新文档,替换文本段落和表格内容,并处理图片插入。此外,还提供了授权检查和文件下载预览功能。
摘要由CSDN通过智能技术生成

适用于有word模版,然后word里面进行字符串替换

工具类

BokeWordUtils

package com.ruoyi.web.controller.tool;

import com.ruoyi.common.utils.StringUtils;
import org.apache.poi.ooxml.POIXMLDocument;
import org.apache.poi.util.Units;
import org.apache.poi.xwpf.usermodel.*;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.math.RoundingMode;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.NumberFormat;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;


public class BokeWordUtils {
    /**
     * 根据模板生成新word文档
     * 判断表格是需要替换还是需要插入,判断逻辑有$为替换,表格无$为插入
     *
     * @param inputUrl 模板存放地址
     * @param file     新文档存放地址
     * @param textMap  需要替换的信息集合
     */
    public static boolean changWord(String inputUrl, File file, Map<String, String> textMap) {
        //模板转换默认成功
        boolean changeFlag = true;
        try {
            //获取docx解析对象
            XWPFDocument document = new XWPFDocument(POIXMLDocument.openPackage(inputUrl));
            //解析替换文本段落对象
            BokeWordUtils.changeText(document, textMap);
            //解析替换表格对象
            BokeWordUtils.changeTable(document, textMap, null);
            //生成新的word
            if (!file.exists()) {
                file.createNewFile();
            }
            FileOutputStream stream = new FileOutputStream(file);
            document.write(stream);
            stream.close();
            System.out.println("成功生成!");
        } catch (IOException e) {
            e.printStackTrace();
            changeFlag = false;
        }


        return changeFlag;

    }

    /**
     * 替换段落文本
     *
     * @param document docx解析对象
     * @param textMap  需要替换的信息集合
     */
    public static void changeText(XWPFDocument document, Map<String, String> textMap) {
        //获取段落集合
        List<XWPFParagraph> paragraphs = document.getParagraphs();
        for (XWPFParagraph paragraph : paragraphs) {
            //判断此段落时候需要进行替换
            String text = paragraph.getText();
            if (checkText(text)) {
                List<XWPFRun> runs = paragraph.getRuns();
                for (XWPFRun run : runs) {

                    //默认:宋体(wps)/等线(office2016) 5号 两端对齐 单倍间距
                    //run.setText("舜发于畎亩之中, 傅说举于版筑之间, 胶鬲举于鱼盐之中, 管夷吾举于士...");
                    run.setBold(true);//加粗
                    run.setCapitalized(false);//我也不知道这个属性做啥的
//runX.setCharacterSpacing(5);//这个属性报错
                    //run.setColor("BED4F1");//设置颜色--十六进制
                    run.setDoubleStrikethrough(false);//双删除线
                    run.setEmbossed(false);//浮雕字体----效果和印记(悬浮阴影)类似
//runX.setFontFamily("宋体");//字体
                    run.setFontFamily("方正粗黑宋简体", XWPFRun.FontCharRange.cs);//字体,范围----效果不详
                    run.setFontSize(11);//字体大小
                    run.setImprinted(false);//印迹(悬浮阴影)---效果和浮雕类似
                    run.setItalic(false);//斜体(字体倾斜)
//runX.setKerning(1);//字距调整----这个好像没有效果
                    run.setShadow(false);//阴影---稍微有点效果(阴影不明显)
//runX.setSmallCaps(true);//小型股------效果不清楚
//runX.setStrike(true);//单删除线(废弃)
                    run.setStrikeThrough(false);//单删除线(新的替换Strike)
//runX.setSubscript(VerticalAlign.SUBSCRIPT);//下标(吧当前这个run变成下标)---枚举
//runX.setTextPosition(20);//设置两行之间的行间距//runX.setUnderline(UnderlinePatterns.DASH_LONG);//各种类型的下划线(枚举)
//runX0.addBreak();//类似换行的操作(html的  br标签)
                    //runX0.addTab();//tab键
                    //runX0.addCarriageReturn();//回车键

                    //替换模板原来位置
                    // run.setText(changeValue(run.toString(), textMap),0);
                    String textValue = changeValue(run.toString(), textMap);
                    run.setText(textValue, 0);
                }
            }
        }
    }

    /**
     * 替换表格对象方法
     *
     * @param document  docx解析对象
     * @param textMap   需要替换的信息集合
     * @param tableList 需要插入的表格信息集合
     */
    public static void changeTable(XWPFDocument document, Map<String, String> textMap,
                                   List<String[]> tableList) {
        //获取表格对象集合
        List<XWPFTable> tables = document.getTables();
        for (int i = 0; i < tables.size(); i++) {
            //只处理行数大于等于2的表格,且不循环表头
            XWPFTable table = tables.get(i);
            if (table.getRows().size() > 1) {
                //判断表格是需要替换还是需要插入,判断逻辑有$为替换,表格无$为插入
                if (checkText(table.getText())) {
                    List<XWPFTableRow> rows = table.getRows();
                    //遍历表格,并替换模板
                    eachTable(rows, textMap);
                } else {
//                  System.out.println("插入"+table.getText());
                    insertTable(table, tableList);
                }
            }
        }
    }


    /**
     * 遍历表格
     *
     * @param rows    表格行对象
     * @param textMap 需要替换的信息集合
     */
    public static void eachTable(List<XWPFTableRow> rows, Map<String, String> textMap) {
        for (XWPFTableRow row : rows) {
            List<XWPFTableCell> cells = row.getTableCells();
            for (XWPFTableCell cell : cells) {
                //插入图片
                if (cell.getText().indexOf("JOB_IMAGE") != -1) {
                    String text = cell.getText().trim().replace("${", "").replace("}", "");
                    //String src = "C:\\Users\\12743\\Pictures\\QQ图片20211202183141.png";
                    String src = textMap.get(text);
                    if (StringUtils.isNotEmpty(src)) {
                        XWPFParagraph newPara = cell.getParagraphArray(0);
                        XWPFRun run = newPara.createRun();
                        try {
                            textMap.put(text, "");
                            File image = new File(src);
                            if (image.exists()) {
                                BufferedImage read = ImageIO.read(image);
                                int width = Units.toEMU(read.getWidth());
                                int height = Units.toEMU(read.getHeight());
                                //1 EMU = 1/914400英寸= 1/36000 mm,16是word文档中图片能设置的最大宽度cm
                                if (width / 360000 > 2.5) {
                                    //向上取整,不要小数
                                    NumberFormat f = NumberFormat.getNumberInstance();
                                    f.setMaximumFractionDigits(0);
                                    f.setRoundingMode(RoundingMode.UP);
                                    //获取图片的EMU和图片在文档中最大EMU的比例值
                                    Double d = width / 360000 / 2.5d;
                                    //根据比例值计算得出适合文档的最大EMU数值
                                    width = Integer.valueOf(f.format(width / d).replace(",", ""));
                                    height = Integer.valueOf(f.format(height / d).replace(",", ""));
                                }
                                run.addPicture(new FileInputStream(src), ImagePojo.getPictureFormat(src), image.getName(), width, height);
                            } else {
                                if (src.indexOf("http") != -1) {
                                    //src = "https://g.csdnimg.cn/common/csdn-footer/images/email.png";
                                    URL url = new URL(src);
                                    HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
                                    httpURLConnection.setConnectTimeout(10 * 1000);
                                    httpURLConnection.setDoInput(true);
                                    httpURLConnection.setRequestMethod("GET");
                                    int responseCode = httpURLConnection.getResponseCode();
                                    InputStream inputStream = null;
                                    if (responseCode == 200) {
                                        inputStream = httpURLConnection.getInputStream();
                                        run.addPicture(inputStream, ImagePojo.getPictureFormat(src), image.getName(), (25 * 36000), (30 * 36000));
                                    }
                                }
                            }
                        } catch (Exception e) {
                            System.out.println("world插入图片异常: " + e.getMessage());
                        }
                    }
                }
                //判断单元格是否需要替换
                if (checkText(cell.getText())) {
                    List<XWPFParagraph> paragraphs = cell.getParagraphs();
                    for (XWPFParagraph paragraph : paragraphs) {
                        List<XWPFRun> runs = paragraph.getRuns();
                        for (XWPFRun run : runs) {
                            //默认:宋体(wps)/等线(office2016) 5号 两端对齐 单倍间距
                            //run.setText("舜发于畎亩之中, 傅说举于版筑之间, 胶鬲举于鱼盐之中, 管夷吾举于士...");
                            run.setBold(false);//加粗
                            run.setCapitalized(false);//我也不知道这个属性做啥的
//runX.setCharacterSpacing(5);//这个属性报错
                            //run.setColor("BED4F1");//设置颜色--十六进制
                            run.setDoubleStrikethrough(false);//双删除线
                            run.setEmbossed(false);//浮雕字体----效果和印记(悬浮阴影)类似
//runX.setFontFamily("宋体");//字体
                            run.setFontFamily("方正粗黑宋简体", XWPFRun.FontCharRange.cs);//字体,范围----效果不详
                            run.setFontSize(11);//字体大小
                            run.setImprinted(false);//印迹(悬浮阴影)---效果和浮雕类似
                            run.setItalic(false);//斜体(字体倾斜)
//runX.setKerning(1);//字距调整----这个好像没有效果
                            run.setShadow(false);//阴影---稍微有点效果(阴影不明显)
//runX.setSmallCaps(true);//小型股------效果不清楚
//runX.setStrike(true);//单删除线(废弃)
                            run.setStrikeThrough(false);//单删除线(新的替换Strike)
//runX.setSubscript(VerticalAlign.SUBSCRIPT);//下标(吧当前这个run变成下标)---枚举
//runX.setTextPosition(20);//设置两行之间的行间距//runX.setUnderline(UnderlinePatterns.DASH_LONG);//各种类型的下划线(枚举)
//runX0.addBreak();//类似换行的操作(html的  br标签)
                            //runX0.addTab();//tab键
                            //runX0.addCarriageReturn();//回车键
                            run.setText(changeValue(run.toString(), textMap), 0);
                        }
                    }
                }
            }
        }
    }

    /**
     * 为表格插入数据,行数不够添加新行
     *
     * @param table     需要插入数据的表格
     * @param tableList 插入数据集合
     */
    public static void insertTable(XWPFTable table, List<String[]> tableList) {
        //创建行,根据需要插入的数据添加新行,不处理表头
        for (int i = 1; i < tableList.size(); i++) {
            XWPFTableRow row = table.createRow();
        }
        //遍历表格插入数据
        List<XWPFTableRow> rows = table.getRows();
        for (int i = 1; i < rows.size(); i++) {
            XWPFTableRow newRow = table.getRow(i);
            List<XWPFTableCell> cells = newRow.getTableCells();
            for (int j = 0; j < cells.size(); j++) {
                XWPFTableCell cell = cells.get(j);
                cell.setText(tableList.get(i - 1)[j]);
            }
        }
    }

    /**
     * 判断文本中时候包含$
     *
     * @param text 文本
     * @return 包含返回true, 不包含返回false
     */
    public static boolean checkText(String text) {
        boolean check = false;
        if (text.indexOf("$") != -1) {
            check = true;
        }
        return check;
    }

    /**
     * 匹配传入信息集合与模板
     *
     * @param value   模板需要替换的区域
     * @param textMap 传入信息集合
     * @return 模板需要替换区域信息集合对应值
     */
    public static String changeValue(String value, Map<String, String> textMap) {
        Set<Entry<String, String>> textSets = textMap.entrySet();
        for (Entry<String, String> textSet : textSets) {
            //匹配模板与替换值 格式${key}
            String key = "${" + textSet.getKey() + "}";
            if (value.indexOf(key) != -1) {
                // value = textSet.getValue();//全部参数替换
                value = value.replace(key, textSet.getValue());//仅替换参数
            }
        }
        //模板未匹配到区域替换为空
        if (checkText(value)) {
            value = "";
        }
        return value;
    }
}

AsposeWordsUtils

package com.ruoyi.web.controller.tool;

import com.aspose.words.Document;
import com.aspose.words.License;
import com.aspose.words.SaveFormat;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;

public class AsposeWordsUtils {

    /**
     * 判断是否有授权文件 如果没有则会认为是试用版,转换的文件会有水印
     *
     * @return
     */
    public static boolean getLicense() {
        boolean result = false;
        try {
            InputStream is = AsposeWordsUtils.class.getClassLoader().getResourceAsStream("license.xml");
            //InputStream is=new FileInputStream("C:/profile/license.xml");
            License aposeLic = new License();
            aposeLic.setLicense(is);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    public static boolean doc2pdf(String sourcerFile, File file) {
        return doc2pdf(sourcerFile, file, true);
    }

    /**
     * Word转PDF操作
     *
     * @param sourcerFile 源文件
     * @param file        目标文件
     * @param licenseFlag  是否判断授权文件(仅测试的时候不判断)
     */
    public static boolean doc2pdf(String sourcerFile, File file, Boolean licenseFlag) {
        boolean flag = true;
        if (licenseFlag && !getLicense()) {// 验证License 若不验证则转化出的pdf文档会有水印产生
            return false;
        }
        try {
            long old = System.currentTimeMillis();

            FileOutputStream os = new FileOutputStream(file);
            Document doc = new Document(sourcerFile);   //sourcerFile是将要被转化的word文档
            doc.save(os, SaveFormat.PDF);//全面支持DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF, EPUB, XPS, SWF 相互转换
            os.close();
            long now = System.currentTimeMillis();
            System.out.println("共耗时:" + ((now - old) / 1000.0) + "秒");  //转化用时
        } catch (Exception e) {
            e.printStackTrace();
            flag = false;
        }
        return flag;
    }

   

}

word,pdf下载预览

    @ResponseBody
    @RequestMapping("/exportDocw")
    @Log(title = "导出")
    public void exportDoc(String xh, HttpServletRequest request, HttpServletResponse response) throws Exception {
        HashMap<String, String> mmap = new HashMap<>();
        //根据xh查询数据
        AjaxResult result = null;
        try {
            result = this.JobXsDetails(xh);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (result != null) {
            JobXs jobXs = (JobXs) result.get("data");
            JobYjstjb jy = jobYjstjbService.selectJobYjstjbByXh(xh);

            //把要展示的字段封装到hashmap里
            String yxdm = String.valueOf(jobXs.getBj());
            mmap.put("xs_yx", yxdm);
            mmap.put("xs_xm", jobXs.getXm());
            mmap.put("xs_xh", xh);
            mmap.put("xs_zy", jobXs.getZydm());
            mmap.put("xs_xb", jobXs.getXbdm());
            mmap.put("xs_zzmm", jobXs.getZzmmdm());
            mmap.put("xs_csny", jobXs.getCsrq());
            mmap.put("xs_mz", jobXs.getMzdm());
         
           

            //null会引起空指针
            for (String key : mmap.keySet()) {
                if (mmap.get(key) == null) {
                    mmap.put(key, "");
                }
            }
      
            //时间戳加8位随机数
            String filePrefix = System.currentTimeMillis() + "_" + (int) ((Math.random() * 9 + 1) * 10000000);
            //word模板地址
            String inputUrl = resourcesPath + "printTemplate/yjsjytjb.docx";
            //打印地址
            String path2 = path + "/template/yjsjy/";
            File pathDirectory = new File(path2);
            if (!pathDirectory.exists()) {
                pathDirectory.mkdirs();
            }
            String inputUrl_doc = path2 + filePrefix + ".docx";
            //参数替换
            BokeWordUtils.changWord(inputUrl, new File(inputUrl_doc), mmap);
            //文件下载
            File pdfFile = new File(inputUrl_doc);
            if (StringUtils.isNotEmpty(inputUrl_doc) && pdfFile.exists()) {
                
                //word打印
                String fileName = FileUtils.setFileDownloadHeader(request, jobXs.getXm() + "xxx表.docx"); 
                //下载与预览的区别: 根据Content-disposition后边接的参数:attachment是下载,inline是预览
                response.setHeader("Content-disposition", "attachment;fileName=" + fileName);
                //如果是下载就不要下面这行代码,预览就打开 
                //response.setContentType("application/pdf");
                //如果是下载就要下面这行代码,预览就不要这行
                response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");

               /*//pdf打印预览
                String xms = xm + "xxx协议书.pdf";
                String fileName = FileUtils.setFileDownloadHeader(request, xms);
                //pdf下载与预览的区别: 根据Content-disposition后边接的参数:attachment是下载,inline是预览
                response.setHeader("Content-disposition", "attachment;fileName=" + fileName);
                response.setContentType("application/pdf");
                //预览就不需要下面这行代码
                response.setContentType("application/vnd.openxmlformats-officedocument.wordprocessingml.document");  */


                FileInputStream in = null;
                try {
                    in = new FileInputStream(pdfFile);
                    OutputStream out = response.getOutputStream();
                    byte[] b = new byte[512];
                    while ((in.read(b)) != -1) {
                        out.write(b);
                    }
                    out.flush();
                    in.close();
                    out.close();
                    //下载完毕后清理文件
                    pdfFile.delete();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值