1. 程式人生 > >poi匯出word2003(動態資料,不用模板,且生成word能再次匯入)

poi匯出word2003(動態資料,不用模板,且生成word能再次匯入)

一、場景需求:
有個專案需要將某個題庫裡面的題目匯出word2003,之前框架裡面沒有匯出word2003的工具類。倒是見過匯出txt,excel的,但是word的沒有。

二、技術選型
網上找了一通,匯出word的有幾個技術方案,不過對於word2003版匯出的例子比較少。

程式匯出word思路(2003版的)
1、利用freemarker來做,xml定義doc的模版,程式動態獲取資料,塞值。這個沒去試了,時間不夠。

2、利用itext來做,能匯出來,據說格式是rtf,能用word開啟。不過poi匯入這個生成的word不支援,poi匯入底層原始碼有對rtf格式做校驗,會拋異常。看過原始碼,但沒有試過用itext來做。

/**
   * Takens an InputStream, verifies that it's not RTF, builds a
   *  POIFSFileSystem from it, and returns that.
   */
  public static POIFSFileSystem verifyAndBuildPOIFS(InputStream istream) throws IOException {
    // Open a PushbackInputStream, so we can peek at the first few bytes
    PushbackInputStream pis = new
PushbackInputStream(istream,6); byte[] first6 = new byte[6]; pis.read(first6); // Does it start with {\rtf ? If so, it's really RTF if(first6[0] == '{' && first6[1] == '\\' && first6[2] == 'r' && first6[3] == 't' && first6[4] == 'f') { throw
new IllegalArgumentException("The document is really a RTF file"); } // OK, so it's not RTF // Open a POIFSFileSystem on the (pushed back) stream pis.unread(first6); return new POIFSFileSystem(pis); }

3、利用poi來做,poi操作word2003,api和demo極少,如果能用07版word的,建議用07,網上07版的例子比較多,也能用07版api自己操作建立段落,頁碼,頁面。本來專案要求03版的。

由於專案要求支援匯出word,也能將匯出的word再次匯入到題庫裡面,因此選用了poi作為03版word匯出。(專案匯入word也是用poi)

三、遇到的問題
1、poi本身對word的支援度就不高,官網的poi匯出word的demo少得可憐。Apache官網自行去搜api吧。
2、用poi匯出word,大多數用模板來做,用個標記語言在程式中和對應的word版本中,程式裡面替換。這篇部落格有寫這個模板替換的
3、專案要求的是動態的資料,題目裡面有不同題型,還有子題,用模板的方式顯然不行。

為此,想對著api,研究一番,不過專案時間緊,趕著上線。和老大溝通過,老大也知道poi對word的支援比較差,demo和api都比較少。不過他覺得既然能匯入,應該也是能匯出的。

只能自己硬著頭皮搞——老大也沒有搞過這個。一開始想著程式拼裝好動態資料,拼成一個html頁面,用poi將html轉成word。是成功了。但是生成的word通過poi再次匯入,報陣列越界之類的。明明用poi匯出,再poi匯入還是有問題。估計是html的word版丟失了一些真正word需要的標記符號之類。

卡在這裡了。

繼續試試api,忽然想起看到api有個range.insertBefore(String text)。這個可能有機會突破。正是這個api,成為了解決問題的關鍵。

最後解決辦法:
poi生成word,先讀取一個空白模版doc進記憶體,用該doc物件的range物件上面提到的方法,插入內容,然後將該range用輸出流寫入到另外一個已存在的空白word文件檔案。ok,能匯出word,這個匯出的word也能通過poi匯入。

通過空白文件的word物件,設定動態資料到該word物件(這裡不會將動態資料寫入到空白文件的檔案當中,僅僅是在記憶體中的),然後再將該有資料的word物件持久化到另外一個word檔案裡面。這樣匯出的word也能通過poi導程序序當中。

String filePath = "xxx要匯出的word.doc";
String wordContent = "動態資料";
        try {
            File doc = new File(filePath) ;
            if(null == doc || !doc.exists()){
                doc.createNewFile() ;
            }

            String realPathFile = "空白的WORD(填充資料所用).doc";//這個空白word需要手動自己建立一個word
            FileInputStream in = new FileInputStream(realPathFile);
            HWPFDocument hwpfDocument = new HWPFDocument(in);
            Range range = hwpfDocument.getRange();//獲取整個空白的word的文件物件
            range.insertBefore(wordContent);//插入資料
            ByteArrayOutputStream ostream = null;
            ostream = new ByteArrayOutputStream();
            hwpfDocument.write(ostream);
            FileOutputStream fos = new FileOutputStream(doc);
            fos.write(ostream.toByteArray());} catch (Exception e) {
            e.printStackTrace(); 
        }

不過,生成的word樣式還是有些問題。每一行的開頭有時候會對不齊,隔了大概一個空白字元。這裡無法設定樣式。不知道有木有朋友也是這樣做。歡迎交流~

動態資料當中是用\r\n和\r作回車和換行的。這裡也有一個坑,windos和linux的回車、換行是不相同的。

幸好,最終還是做出來了。用了兩天不到的時間。附上女神的照片,做福利啦

相關推薦

poi匯出word2003動態資料不用模板生成word再次匯入

一、場景需求: 有個專案需要將某個題庫裡面的題目匯出word2003,之前框架裡面沒有匯出word2003的工具類。倒是見過匯出txt,excel的,但是word的沒有。 二、技術選型 網上找了一通,匯出word的有幾個技術方案,不過對於word2003版

POI匯出時寫一份到ftp伺服器一份下載給客戶端 ftp伺服器搭建(離線安裝vsftpd)配置 poi實現百萬級資料匯出 oi實現百萬級資料匯出

導語:   昨天接到專案經理這麼一個需求,讓我在POI匯出Excel的時候寫一份到我之前搭建的ftp伺服器上。所以就有了這篇部落格首先我們來分析下之前的業務邏輯:我們建立並構造了一個workbook,然後構建了一個OutputStream輸出流,然後我們把資料寫入輸出流中就可以被客戶端下載。   現在我們

《物聯網框架ServerSuperIO教程》- 23.動態資料介面增加快取提高資料輸出到OPCServer和實時資料庫的效率

 22.1   概述及要解決的問題       裝置驅動有DeviceDynamic介面,可以繼承並增加新的實時資料屬性,每次通訊完成後更新這些屬性資料。原來是通過DeviceDynamic介面實體類反射的方式獲得最新的實時資料,並輸出到關係資料庫、實時資料庫和OPC Server等介面。      但是

小程式之多列選擇器動態資料支援2345...列

程式碼分兩部分,先上wxml <view class="container"> <form catchsubmit="formSubmit"> <view class="form-card"> <view class="weui-

2019年考研政治必考點參考資料 腿姐四米鵬六肖八徐濤押題20題

文章目錄 選擇題核心考點 馬原 毛中特 史綱 思修法基 當代政經 分析題背誦 典型例題 選擇題核心考點

java根據模板匯出pdf動態增加模板頁數

這兩天碰到了一個根據模板匯出pdf的需求,研究了幾天以後,發現網上的資料不太齊全,主要是沒找到既根據模板匯出,又可以動態增加頁數的例子。只能通過各種資料結合來實現這個需求了(其實是懶得看iText英文文件,這個以後得改過來)。 下面先來說下pdf匯出主要的兩種方

Morris Traversal方法遍歷二叉樹非遞迴不用O(1)空間

本文主要解決一個問題,如何實現二叉樹的前中後序遍歷,有兩個要求: 1. O(1)空間複雜度,即只能使用常數空間; 2. 二叉樹的形狀不能被破壞(中間過程允許改變其形狀)。 通常,實現二叉樹的前序(preorder)、中序(inorder)、後序(postorder)遍歷有兩個常用的方法:一是遞迴(rec

Java POI 匯出Excel

序言上篇序言已經說明了我為什麼要寫這個教程了,如果想知道請戳這個連結:序言。那麼廢話就不多說開始吧。POI Maven 依賴 <dependencies> <dependency> <groupId>org.apache.poi&

POI匯出Excel

匯出樣式如下: ============================================================== 工具類: package com.util; import java.io.File; import java.io.File

POI匯出Excel

匯出樣式如下: ======================================================================================== 工具類: package com.util; import java.io

angular 建立一個簡單的屬性型指令 動態獲取DOM元素size對DOM樣式進行改變

一. 在 Angular 中有三種類型的指令:1. 元件 — 擁有模板的指令2. 結構型指令 — 通過新增和移除 DOM 元素改變 DOM 佈局的指令3. 屬性型指令 — 改變元素、元件或其它指令的外觀和行為的指令。本章主要想介紹一下屬性型指令並建立一個簡單的屬性型指令,屬性

jquery的treeview外掛 呼叫樣例動態資料

參考: http://www.zhuoda.org/irini/83891.htmlhttp://www.pin5i.com/showtopic-23119.htmlhttp://king130520.iteye.com/blog/974628http://www.cnbl

treeview控制元件動態資料繫結+整行選擇)(WPF)

上一篇中介紹了動態繫結資料庫的方法,本篇中將會介紹整行選擇的方法 <local:IndentConverter x:Key="ConverterLoginMarginLeft"/>         <!--treeview控制元件的樣式-->

hive 分割槽partition表 建立 資料匯入動態分割槽插入、靜態分割槽插入、動靜態混合插入

學習《hive 程式設計指南》一書,整理的知識,所以文章例子出自此書。 分割槽建立與資料匯入的步驟: 1.建立分割槽表(以外部分割槽表為例)       create external table if not exists dividends(         ymd

Java框架-SpringMVC的應用json資料互動、控制器方法返回值、檔案上傳

1. 搭建SpringMVC開發環境 1.1 建立專案,新增依賴 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" x

JavaScript的函式定義與解析、匿名函式、函式傳參、return關鍵字和陣列操作資料的方法、多維陣列、陣列去重

函式 函式就是重複執行的程式碼片。 1、函式定義與執行 <script type="text/javascript"> // 函式定義 function aa(){ alert('hello!'); } // 函式執行

Windows還是Ubuntu重灌系統不用傻瓜式安裝

程式猿:妹子電腦裝系統不用愁!Windows還是Ubuntu都搞定! 重灌系統是不是很麻煩?是不是很煩重灌系統,什麼windows,什麼Ubuntu(linux),看上去就麻煩,那麼小編今天就給你科普一下這些重灌電腦的難度! windows重灌 如果你本身是windows,還想重灌

C++模板的實現模板函式和模板附帶模板實現順序表和連結串列程式碼

模板  當我們實現一個交換函式時,我們可以寫成如下。 void Swap(int& x, int& y) { int tmp = x; x = y; y = tmp; }  這裡只能交換兩個整數,當我們

日期大小比較不用ifwhile, switch、for、三目運算子等

#include <iostream> using namespace std; struct DATE {     int year, month, day;      //三個變

Maven依賴下載速度慢不用這麼搞快了飛起

一、背景 眾所周知,Maven對於依賴的管理讓我們程式設計師感覺爽的不要不要的,但是由於這貨是國外出的,所以在我們從中央倉庫下載依賴的時候,速度如蝸牛一般,讓人不能忍,並且這也是大多數程式設計師都會遇到的問題。今天我們就教大家一招來完美解決這個問題,從此遠離下載依賴速度極慢的困擾。 二、原理及解決方式