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文件替換出來的字體不能匹配碌廓。