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等介面。 但是
小程式之多列選擇器(動態資料,支援2,3,4,5...列)
程式碼分兩部分,先上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; } 這裡只能交換兩個整數,當我們
日期大小比較,不用if,while, switch、for、三目運算子等
#include <iostream> using namespace std; struct DATE { int year, month, day; //三個變
Maven依賴下載速度慢,不用怕,這麼搞快了飛起
一、背景 眾所周知,Maven對於依賴的管理讓我們程式設計師感覺爽的不要不要的,但是由於這貨是國外出的,所以在我們從中央倉庫下載依賴的時候,速度如蝸牛一般,讓人不能忍,並且這也是大多數程式設計師都會遇到的問題。今天我們就教大家一招來完美解決這個問題,從此遠離下載依賴速度極慢的困擾。 二、原理及解決方式