word轉(zhuǎn)pdf

1.功能實現(xiàn)

使用poi對進行word文件進行解析處理,使用aspose進行pdf轉(zhuǎn)換

aspose下載路徑:https://pan.baidu.com/s/1vJWgYAAaHpnXmyKhZa4ljg 提取碼:jdwp

注:如果導入了easyExcel姥宝,則只需要導入一部分poi(關(guān)于doc文件的解析)隧出,防止版本不一致的問題

2.導入依賴

       <dependency>
          <groupId>org.apache.poi</groupId>
          <artifactId>poi-ooxml</artifactId>
          <version>3.17</version>
      </dependency>
      <dependency>
          <groupId>org.apache.poi</groupId>
          <artifactId>poi</artifactId>
          <version>3.17</version>
      </dependency>
      <dependency>
          <groupId>org.apache.poi</groupId>
          <artifactId>poi-ooxml-schemas</artifactId>
          <version>3.17</version>
      </dependency>
      <!--如果導入了easyExcel的导绷,只需要導入下面這個-->
      <dependency>
              <groupId>org.apache.poi</groupId>
              <artifactId>poi-scratchpad</artifactId>
              <version>3.17</version>
          </dependency>
      <!--aspose,用于word轉(zhuǎn)pdf,此處我是將本地jar包導入了maven(將jar導入maven的方法前面有說過)-->
     <dependency>
              <groupId>com.aspose.words</groupId>
              <artifactId>com-aspose-words-1.1</artifactId>
              <version>1.1.1</version>
          </dependency>

3.獲取word文件薇宠,替換其中的特殊字符:${name}

處理docx文件必須表格和段落分開處理阱当,doc文件則不需要單獨處理

   /**
     * 替換word模板的字符預覽或者下載
     *
     * @param inputStream 文件輸入流
     * @param outputStream 文件輸出流
     * @param map ${name}的key的數(shù)據(jù)
     * @param type 下載或者預覽
     * @return
     */
    public static byte[] replaceWord(InputStream inputStream, OutputStream outputStream, Map<String, String> map, Integer type, String fileType) {
        try {
             //doc文件處理
            if ("doc".equals(fileType)) {
                HWPFDocument document = new HWPFDocument(inputStream);
                replaceDocText(map, document);
                //預覽
                if (type == 1) {
                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
                    //3.輸出流
                    document.write(baos);
                    return baos.toByteArray();
                }
                //下載
                document.write(outputStream);
            }
            if ("docx".equals(fileType)) {
              //docx文件處理
                XWPFDocument document = new XWPFDocument(inputStream);
                //替換段落
                replaceDocxTable(map, document);
                //替換文本
                replaceDocxText(map, document);
                //預覽
                if (type == 1) {
                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
                    //3.輸出流
                    document.write(baos);
                    return baos.toByteArray();
                }
                //下載
                document.write(outputStream);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

/**
     * 替換Docx表格
     *
     * @param map
     * @param document
     */
    private static void replaceDocxTable(Map<String, String> map, XWPFDocument document) {
        //2. 替換表格中的指定文字(本人模板中 對應的姓名争拐、性別等)
        Iterator<XWPFTable> itTable = document.getTablesIterator();
        XWPFTable table;
        int rowsCount;
        while (itTable.hasNext()) {
            table = itTable.next();
            rowsCount = table.getNumberOfRows();
            for (int i = 0; i < rowsCount; i++) {
                XWPFTableRow row = table.getRow(i);
                List<XWPFTableCell> cells = row.getTableCells();
                for (XWPFTableCell cell : cells) {
                    for (Map.Entry<String, String> e : map.entrySet()) {
                        if (cell.getText().equals(e.getKey())) {
                            XWPFParagraph xwpfParagraph = cell.addParagraph();
                            cell.removeParagraph(0);
                            //設置單元格文本樣式
                            XWPFRun run1 = xwpfParagraph.createRun();
                            run1.setFontSize(11);
                            run1.setText(e.getValue());
                            //設置內(nèi)容水平居中
                            CTTc cttc = cell.getCTTc();
                            CTTcPr ctPr = cttc.addNewTcPr();
                            ctPr.addNewVAlign().setVal(STVerticalJc.CENTER);
                        }
                    }
                }
            }
        }
    }


    /**
     * 替換Docx文本或者段落
     *
     * @param map
     * @param document
     */
    private static void replaceDocxText(Map<String, String> map, XWPFDocument document) {
        // 替換段落中的指定文字
        Iterator<XWPFParagraph> itPara = document.getParagraphsIterator();
        while (itPara.hasNext()) {
            XWPFParagraph paragraph = itPara.next();
            List<XWPFRun> runs = paragraph.getRuns();
            for (XWPFRun run : runs) {
                String oneparaString = run.getText(run.getTextPosition());
                if (StringUtils.isBlank(oneparaString)) {
                    continue;
                }
                for (Map.Entry<String, String> entry : map.entrySet()) {
                    oneparaString = oneparaString.replace(entry.getKey(), entry.getValue());
                }
                run.setText(oneparaString, 0);
            }
        }
    }

    /**
     * 替換doc文件
     *
     * @param map
     * @param document
     */
    private static void replaceDocText(Map<String, String> map, HWPFDocument document) {
        Range range = document.getRange();
        for (Map.Entry<String, String> entry : map.entrySet()) {
            if (entry.getValue() == null) {
                entry.setValue("  ");
            }
            range.replaceText(entry.getKey(), entry.getValue());
        }
    }

4.生成pdf預覽

破解生成的水印

<!--將以下內(nèi)容放在新建文件license.xml中-->
<License>
    <Data>
        <Products>
            <Product>Aspose.Total for Java</Product>
            <Product>Aspose.Words for Java</Product>
        </Products>
        <EditionType>Enterprise</EditionType>
        <SubscriptionExpiry>20991231</SubscriptionExpiry>
        <LicenseExpiry>20991231</LicenseExpiry>
        <SerialNumber>8bfe198c-7f0c-4ef8-8ff0-acc3237bf0d7</SerialNumber>
    </Data>
    <Signature>sNLLKGMUdF0r8O1kKilWAGdgfs2BvJb/2Xp8p5iuDVfZXmhppo+d0Ran1P9TKdjV4ABwAgKXxJ3jcQTqE/2IRfqwnPf8itN8aFZlV3TJPYeD3yWE7IT55Gz6EijUpC7aKeoohTb4w2fpox58wWoF3SNp6sK6jDfiAUGEHYJ9pjU=</Signature>
</License>

讀取破解文件

    /**
     * 去掉aspose的水印
     *
     * @return
     */
    private static boolean getLicense() {
        boolean result = false;
        try {
            ClassPathResource cpr = new ClassPathResource("static" + File.separator + "license.xml");
            InputStream is = cpr.getInputStream();
            License aposeLic = new License();
            aposeLic.setLicense(is);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }
    //word轉(zhuǎn)pdf
    public static void wordToPdf(InputStream inputStream, OutputStream outputStream) {
        if (!getLicense()) { // 驗證License 若不驗證則轉(zhuǎn)化出的pdf文檔會有水印產(chǎn)生
            return;
        }
        try {
            long old = System.currentTimeMillis();
            com.aspose.words.Document doc = new com.aspose.words.Document(inputStream); //inputStream是將要被轉(zhuǎn)化的word文檔
            doc.save(outputStream, com.aspose.words.SaveFormat.PDF);//全面支持DOC, DOCX, OOXML, RTF HTML, OpenDocument, PDF, EPUB, XPS, SWF 相互轉(zhuǎn)換
            long now = System.currentTimeMillis();
            outputStream.close();
            System.out.println("共耗時:" + ((now - old) / 1000.0) + "秒"); //轉(zhuǎn)化用時
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

5.下載和預覽中的response設置

  //預覽
  response.setContentType("application/pdf;charset=UTF-8");
  //inline設置是強制瀏覽器顯示茄茁,attachment設置時強制瀏覽器下載
  response.setHeader("Content-Disposition", "inline; filename= file");

//下載
 response.setContentType("application/octet-stream");
 String fileName = fileEntity.getFileName();
 response.setHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode(fileName, "utf-8"));
response.flushBuffer();

6.問題

1.如果發(fā)現(xiàn)讀取word文件失敗鹰祸,可能是word文件后綴與原始后綴不一致,如:新建一個doc,修改為后綴docx,這是讀取不了的跟继。
2.部署在linux种冬,預覽出現(xiàn)亂碼或者空白,是因為缺少字體導致
3.建議優(yōu)先選擇doc格式文件还栓,因為docx文件替換出來的字體不能匹配碌廓。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末传轰,一起剝皮案震驚了整個濱河市剩盒,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌慨蛙,老刑警劉巖辽聊,帶你破解...
    沈念sama閱讀 217,734評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異期贫,居然都是意外死亡跟匆,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評論 3 394
  • 文/潘曉璐 我一進店門通砍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來玛臂,“玉大人烤蜕,你說我怎么就攤上這事〖T” “怎么了讽营?”我有些...
    開封第一講書人閱讀 164,133評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長泡徙。 經(jīng)常有香客問我橱鹏,道長,這世上最難降的妖魔是什么堪藐? 我笑而不...
    開封第一講書人閱讀 58,532評論 1 293
  • 正文 為了忘掉前任莉兰,我火速辦了婚禮,結(jié)果婚禮上礁竞,老公的妹妹穿的比我還像新娘糖荒。我一直安慰自己,他們只是感情好模捂,可當我...
    茶點故事閱讀 67,585評論 6 392
  • 文/花漫 我一把揭開白布寂嘉。 她就那樣靜靜地躺著,像睡著了一般枫绅。 火紅的嫁衣襯著肌膚如雪泉孩。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,462評論 1 302
  • 那天并淋,我揣著相機與錄音寓搬,去河邊找鬼。 笑死县耽,一個胖子當著我的面吹牛句喷,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播兔毙,決...
    沈念sama閱讀 40,262評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼唾琼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了澎剥?” 一聲冷哼從身側(cè)響起锡溯,我...
    開封第一講書人閱讀 39,153評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎哑姚,沒想到半個月后祭饭,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,587評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡叙量,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,792評論 3 336
  • 正文 我和宋清朗相戀三年倡蝙,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片绞佩。...
    茶點故事閱讀 39,919評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡寺鸥,死狀恐怖猪钮,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情胆建,我是刑警寧澤躬贡,帶...
    沈念sama閱讀 35,635評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站眼坏,受9級特大地震影響拂玻,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜宰译,卻給世界環(huán)境...
    茶點故事閱讀 41,237評論 3 329
  • 文/蒙蒙 一檐蚜、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧沿侈,春花似錦闯第、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,855評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至蛛淋,卻和暖如春咙好,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背褐荷。 一陣腳步聲響...
    開封第一講書人閱讀 32,983評論 1 269
  • 我被黑心中介騙來泰國打工勾效, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人叛甫。 一個月前我還...
    沈念sama閱讀 48,048評論 3 370
  • 正文 我出身青樓层宫,卻偏偏與公主長得像,于是被迫代替她去往敵國和親其监。 傳聞我的和親對象是個殘疾皇子萌腿,可洞房花燭夜當晚...
    茶點故事閱讀 44,864評論 2 354

推薦閱讀更多精彩內(nèi)容