此例通過docx4j實現(xiàn)word轉(zhuǎn)成pdf元咙。
因功能較簡單君纫,只在此展示一下后臺功能代碼譬猫。
1.公用方法類
package com.ldht.common.util.wordPdf;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.apache.poi.POIXMLDocument;
import org.apache.poi.util.IOUtils;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.docx4j.convert.out.pdf.PdfConversion;
import org.docx4j.convert.out.pdf.viaXSLFO.PdfSettings;
import org.docx4j.fonts.IdentityPlusMapper;
import org.docx4j.fonts.Mapper;
import org.docx4j.fonts.PhysicalFonts;
import org.docx4j.jaxb.Context;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.PartName;
import org.docx4j.openpackaging.parts.WordprocessingML.AlternativeFormatInputPart;
import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart;
import org.docx4j.relationships.Relationship;
import org.docx4j.wml.CTAltChunk;
/**
* @author HMZ
*/
public class WordUtil {
public void mergeDocx(HttpServletResponse response,List<String> list){
List<InputStream> inList=new ArrayList<InputStream>();
for(int i=0;i<list.size();i++)
try {
inList.add(new FileInputStream(list.get(i)));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
InputStream inputStream=mergeDocx(inList);
saveTemplate(response,inputStream);
} catch ( IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Docx4JException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public InputStream mergeDocx(final List<InputStream> streams) throws Docx4JException, IOException {
WordprocessingMLPackage target = null;
final File generated = File.createTempFile("generated", ".docx");
int chunkId = 0;
Iterator<InputStream> it = streams.iterator();
while (it.hasNext()) {
InputStream is = it.next();
if (is != null) {
if (target == null) {
// Copy first (master) document
OutputStream os = new FileOutputStream(generated);
os.write(IOUtils.toByteArray(is));
os.close();
target = WordprocessingMLPackage.load(generated);
} else {
// Attach the others (Alternative input parts)
insertDocx(target.getMainDocumentPart(),
IOUtils.toByteArray(is), chunkId++);
}
}
}
if (target != null) {
target.save(generated);
FileInputStream input = new FileInputStream(generated);
//獲取docx解析對象
// XWPFDocument document = new XWPFDocument(target);
return new FileInputStream(generated);
} else {
return null;
}
}
// 插入文檔
private void insertDocx(MainDocumentPart main, byte[] bytes, int chunkId) {
try {
AlternativeFormatInputPart afiPart = new AlternativeFormatInputPart(
new PartName("/part" + chunkId + ".docx"));
// afiPart.setContentType(new ContentType(CONTENT_TYPE));
afiPart.setBinaryData(bytes);
Relationship altChunkRel = main.addTargetPart(afiPart);
CTAltChunk chunk = Context.getWmlObjectFactory().createCTAltChunk();
chunk.setId(altChunkRel.getId());
main.addObject(chunk);
} catch (Exception e) {
e.printStackTrace();
}
}
public void saveTemplate(HttpServletResponse response,InputStream fis) throws IOException{
OutputStream fos = response.getOutputStream();
int bytesum = 0;
int byteread = 0;
try {
byte[] buffer = new byte[10240];
while ( (byteread = fis.read(buffer)) != -1) {
bytesum += byteread; //字節(jié)數(shù) 文件大小
fos.write(buffer, 0, byteread);
}
fis.close();
fos.close();
} catch (FileNotFoundException e1) {
e1.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* docx文檔轉(zhuǎn)換為PDF
* @param docx docx文檔
* @param pdfPath PDF文檔存儲路徑
* @throws Exception 可能為Docx4JException, FileNotFoundException, IOException等
*/
@SuppressWarnings("deprecation")
public void convertDocxToPDF(File docx, String pdfPath) throws Exception {
OutputStream os = null;
try {
WordprocessingMLPackage mlPackage = WordprocessingMLPackage.load(docx);
// Mapper fontMapper = new BestMatchingMapper();
Mapper fontMapper = new IdentityPlusMapper();
//中文字體轉(zhuǎn)換
fontMapper.getFontMappings().put("華文行楷", PhysicalFonts.getPhysicalFonts().get("STXingkai"));
fontMapper.getFontMappings().put("隸書", PhysicalFonts.getPhysicalFonts().get("LiSu"));
fontMapper.getFontMappings().put("宋體",PhysicalFonts.getPhysicalFonts().get("SimSun"));
fontMapper.getFontMappings().put("微軟雅黑",PhysicalFonts.getPhysicalFonts().get("Microsoft Yahei"));
fontMapper.getFontMappings().put("黑體",PhysicalFonts.getPhysicalFonts().get("SimHei"));
fontMapper.getFontMappings().put("楷體",PhysicalFonts.getPhysicalFonts().get("KaiTi"));
fontMapper.getFontMappings().put("新宋體",PhysicalFonts.getPhysicalFonts().get("NSimSun"));
fontMapper.getFontMappings().put("華文行楷", PhysicalFonts.getPhysicalFonts().get("STXingkai"));
fontMapper.getFontMappings().put("華文仿宋", PhysicalFonts.getPhysicalFonts().get("STFangsong"));
fontMapper.getFontMappings().put("宋體擴展",PhysicalFonts.getPhysicalFonts().get("simsun-extB"));
fontMapper.getFontMappings().put("仿宋",PhysicalFonts.getPhysicalFonts().get("FangSong"));
fontMapper.getFontMappings().put("仿宋_GB2312",PhysicalFonts.getPhysicalFonts().get("FangSong_GB2312"));
fontMapper.getFontMappings().put("幼圓",PhysicalFonts.getPhysicalFonts().get("YouYuan"));
fontMapper.getFontMappings().put("華文宋體",PhysicalFonts.getPhysicalFonts().get("STSong"));
fontMapper.getFontMappings().put("華文中宋",PhysicalFonts.getPhysicalFonts().get("STZhongsong"));
mlPackage.setFontMapper(fontMapper);
PdfConversion conversion = new org.docx4j.convert.out.pdf.viaXSLFO.Conversion(mlPackage);
os = new FileOutputStream(pdfPath);
conversion.output(os, new PdfSettings());
} finally {
IOUtils.closeQuietly(os);
}
}
/**
* 將文件內(nèi)容寫入到臨時文件中
* @param inputUrl
* @param file
* @throws IOException
*/
public void createFile(String inputUrl,File file) throws IOException{
//獲取docx解析對象
XWPFDocument document = new XWPFDocument(POIXMLDocument.openPackage(inputUrl));
FileOutputStream stream = new FileOutputStream(file);
document.write(stream);
stream.close();
}
/**
* 替換文本
* @param document docx解析對象
*/
public static void changeText(XWPFDocument document, String oldValue, String newValue){
//獲取段落集合
List<XWPFParagraph> paragraphs = document.getParagraphs();
for (XWPFParagraph paragraph : paragraphs) {
//判斷此段落時候需要進行替換
String text = paragraph.getText();
if(text.indexOf("^m^p")!= -1 || text.indexOf("^p^m")!= -1){
List<XWPFRun> runs = paragraph.getRuns();
for (XWPFRun run : runs) {
//替換模板原來位置
run.setText("^m",0);
}
}
}
}
}
2.如何調(diào)用
WordUtil.convertDocxToPDF(wordFile,pdfFilePath);
3.說明
convertDocxToPDF方法中定義的fontMapper,用于存放各類字體的轉(zhuǎn)換關(guān)系俭茧,若不聲明开皿,則轉(zhuǎn)換后有可能出現(xiàn)亂碼涧黄。word中盡量使用宋體等常用字體篮昧,包括在Linux系統(tǒng)中,也需要安裝相應(yīng)的字體弓熏,才能解決亂碼問題。