Java多種方法靜態生成doc文檔。本站提示廣大學習愛好者:(Java多種方法靜態生成doc文檔)文章只能為提供參考,不一定能成為您想要的結果。以下是Java多種方法靜態生成doc文檔正文
原來是要在Android端生成doc的(這需求...),最初辦法沒有好的辦法可以或許在Android上做到完善,最初照樣只能搬家到辦事器。不糟蹋,照樣記載下各框架不支撐Android的緣由和他們的特色。Java相干的這類框架照樣許多的,有幾個還不錯,惋惜要末不支撐Android,要末要免費討價格不低。
經由親身測試,Android不支撐Java的awt許多包不克不及直接在Android上用,FreeMarker挺不錯的,能生成龐雜英俊的doc,惋惜不支撐Android。用POI在Android上能運轉,然則一路由於版本,格局等走了許多坑,用WFS翻開照樣亂碼。Jword、Aspose.word能完善支撐,Jword試用期只要30天二者免費都不菲。itext沒有測試,不外據說也不支撐Android。
辦法一:freemarker
該辦法須要先手動創立一個doc模板(圖片記得應用占位符),並保留為xml文件。經由過程靜態調換特定標簽${}中的內容生成。example:
先上後果圖:
public class DocUtil { public Configuration configure=null; public DocUtil(){ configure=new Configuration(Configuration.VERSION_2_3_22); configure.setDefaultEncoding("utf-8"); } /** * 依據Doc模板生成word文件 * @param dataMap 須要填入模板的數據 * @param downloadType 文件稱號 * @param savePath 保留途徑 */ public void createDoc(Map<String,Object> dataMap,String downloadType,String savePath){ try { //加載須要裝填的模板 Template template=null; //設置模板裝配辦法和途徑,FreeMarker支撐多種模板裝載辦法。可以重servlet,classpath,數據庫裝載。 //加載模板文件,放在testDoc下 configure.setClassForTemplateLoading(this.getClass(), "/testDoc"); //設置對象包裝器 // configure.setObjectWrapper(new DefaultObjectWrapper()); //設置異常處置器 configure.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER); //界說Template對象,留意模板類型名字與downloadType要分歧 template=configure.getTemplate(downloadType+".xml"); File outFile=new File(savePath); Writer out=null; out=new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outFile), "utf-8")); template.process(dataMap, out); out.close(); } catch (IOException e) { e.printStackTrace(); } catch (TemplateException e) { e.printStackTrace(); } } public String getImageStr(String imgFile){ InputStream in=null; byte[] data=null; try { in=new FileInputStream(imgFile); data=new byte[in.available()]; in.read(data); in.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } BASE64Encoder encoder=new BASE64Encoder(); return encoder.encode(data); } }
public class TestDoc { public static void main(String[] args) { DocUtil docUtil=new DocUtil(); Map<String, Object> dataMap=new HashMap<String, Object>(); dataMap.put("name", "Joanna"); dataMap.put("examNum", "111111111111"); dataMap.put("IDCard", "222222222222222222"); dataMap.put("carModel", "C1"); dataMap.put("drivingSchool", "測試駕校"); dataMap.put("busyType", "首次申領"); dataMap.put("examDate", "2016-03-10"); dataMap.put("orderCount", "第1次"); dataMap.put("userImg1", docUtil.getImageStr("D:\\Img\\userImg1.png")); dataMap.put("userImg2", docUtil.getImageStr("D:\\Img\\userImg2.png")); dataMap.put("firstExamTime", "12:41:17-12:44:38"); dataMap.put("firstExamScores", "0分,不合格"); dataMap.put("firstDeductItem", "12:44:15 20102 1號倒車入庫,車身出線 扣100分"); dataMap.put("firstPic1", docUtil.getImageStr("D:\\Img\\firstPic1.png")); dataMap.put("firstPic2", docUtil.getImageStr("D:\\Img\\firstPic2.png")); dataMap.put("firstPic3", docUtil.getImageStr("D:\\Img\\firstPic3.png")); dataMap.put("secondExamTime", "12:46:50-13:05:37"); dataMap.put("secondExamScores", "90分,經由過程"); dataMap.put("secondDeductItem", ""); dataMap.put("secondPic1", docUtil.getImageStr("D:\\Img\\secondPic1.png")); dataMap.put("secondPic2", docUtil.getImageStr("D:\\Img\\secondPic2.png")); dataMap.put("secondPic3", docUtil.getImageStr("D:\\Img\\secondPic3.png")); docUtil.createDoc(dataMap, "baseDoc", "D:\\yanqiong.doc"); } }
xml文件太長,就不貼了...
最初附上Android不克不及應用的緣由:http://stackoverflow.com/questions/25929542/use-freemarker-library-in-android
彌補關於靜態顯示list和換行的成績
需求明白到:在下面的扣分項中,假如我有幾條扣分項,我願望每顯示一條換行。
直接在要顯示的內容上加換行符,並沒有甚麼後果,起不到換行的感化。
個中在加ftl標簽時,如<#list></list>,就會湧現一些成績,在xml中其實不辨認,招致項目不克不及運轉。
處理:
在須要顯示多條扣分項的地位加,並加換行符:
<#list firstDeductItem as firstItem>
<w:t>${firstItem}</w:t><w:br/>
</#list>
TestDoc.java中改成:
List<String> Strs=new ArrayList<String>();
Strs.add("1111111111111111111");
Strs.add("222222222222222");
Strs.add("333333333333333");
dataMap.put("firstDeductItem", Strs);
DocUtil.java中改成:
//界說Template對象,留意模板類型名字與downloadType要分歧
template=configure.getTemplate(downloadType+".ftl");此時xml文件會報錯,固然也不克不及編譯運轉項目,須要將.xml文件改成.ftl文件保留。再編譯運轉,後果圖:
辦法二:POI
用這個辦法碰到了許多版本成績,這裡是基於POI3.7+Word2007的,測試可以或許完善運轉。
你須要用Word2007手動生成文檔模板(用其他的生成會報錯:沒法翻開文件),並用${}調換須要靜態更新的內容,與下面相似,然則不須要你保留為xml文檔格局了。
/** * 自界說XWPFDocument,偏重寫createPicture()辦法 * @author Joanna.Yan * */ public class CustomXWPFDocument extends XWPFDocument{ public CustomXWPFDocument(InputStream in) throws IOException{ super(in); } public CustomXWPFDocument(){ super(); } public CustomXWPFDocument(OPCPackage pkg) throws IOException{ super(pkg); } public void createPicture(int id,int width,int height,XWPFParagraph paragraph){ final int EMU=9525; width *=EMU; height *=EMU; String blipId=((POIXMLDocumentPart) getAllPictures().get(id)).getPackageRelationship().getId(); CTInline inline=paragraph.createRun().getCTR().addNewDrawing().addNewInline(); String picXml="" + "<a:graphic xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\">" + " <a:graphicData uri=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">" + " <pic:pic xmlns:pic=\"http://schemas.openxmlformats.org/drawingml/2006/picture\">" + " <pic:nvPicPr>" + " <pic:cNvPr id=\"" + id + "\" name=\"Generated\"/>" + " <pic:cNvPicPr/>" + " </pic:nvPicPr>" + " <pic:blipFill>" + " <a:blip r:embed=\"" + blipId + "\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"/>" + " <a:stretch>" + " <a:fillRect/>" + " </a:stretch>" + " </pic:blipFill>" + " <pic:spPr>" + " <a:xfrm>" + " <a:off x=\"0\" y=\"0\"/>" + " <a:ext cx=\"" + width + "\" cy=\"" + height + "\"/>" + " </a:xfrm>" + " <a:prstGeom prst=\"rect\">" + " <a:avLst/>" + " </a:prstGeom>" + " </pic:spPr>" + " </pic:pic>" + " </a:graphicData>" + "</a:graphic>"; inline.addNewGraphic().addNewGraphicData(); XmlToken xmlToken=null; try { xmlToken=XmlToken.Factory.parse(picXml); } catch (XmlException e) { e.printStackTrace(); } inline.set(xmlToken); inline.setDistT(0); inline.setDistB(0); inline.setDistL(0); inline.setDistR(0); CTPositiveSize2D extent=inline.addNewExtent(); extent.setCx(width); extent.setCy(height); CTNonVisualDrawingProps docPr=inline.addNewDocPr(); docPr.setId(id); docPr.setName("圖片"+id); docPr.setDescr("測試"); } }
/** * 實用於word 2007 * poi版本 3.7 * @author Joanna.Yan * */ public class WordUtil { public static CustomXWPFDocument generateWord(Map<String, Object> param,String template){ CustomXWPFDocument doc=null; try { OPCPackage pack=POIXMLDocument.openPackage(template); doc=new CustomXWPFDocument(pack); if(param!=null&¶m.size()>0){ //處置段落 List<XWPFParagraph> paragraphList = doc.getParagraphs(); processParagraphs(paragraphList, param, doc); //處置表格 Iterator<XWPFTable> it = doc.getTablesIterator(); while(it.hasNext()){ XWPFTable table = it.next(); List<XWPFTableRow> rows = table.getRows(); for (XWPFTableRow row : rows) { List<XWPFTableCell> cells = row.getTableCells(); for (XWPFTableCell cell : cells) { List<XWPFParagraph> paragraphListTable = cell.getParagraphs(); processParagraphs(paragraphListTable, param, doc); } } } } } catch (IOException e) { e.printStackTrace(); } return doc; } /** * 處置段落 * @param paragraphList * @param param * @param doc */ public static void processParagraphs(List<XWPFParagraph> paragraphList,Map<String, Object> param,CustomXWPFDocument doc){ if(paragraphList!=null&¶graphList.size()>0){ for (XWPFParagraph paragraph : paragraphList) { List<XWPFRun> runs=paragraph.getRuns(); for (XWPFRun run : runs) { String text=run.getText(0); if(text!=null){ boolean isSetText=false; for (Entry<String, Object> entry : param.entrySet()) { String key=entry.getKey(); if(text.indexOf(key)!=-1){ isSetText=true; Object value=entry.getValue(); if(value instanceof String){//文本調換 text=text.replace(key, value.toString()); }else if(value instanceof Map){//圖片調換 text=text.replace(key, ""); Map pic=(Map) value; int width=Integer.parseInt(pic.get("width").toString()); int height=Integer.parseInt(pic.get("height").toString()); int picType=getPictureType(pic.get("type").toString()); byte[] byteArray = (byte[]) pic.get("content"); ByteArrayInputStream byteInputStream = new ByteArrayInputStream(byteArray); try { int ind = doc.addPicture(byteInputStream,picType); doc.createPicture(ind, width , height,paragraph); } catch (InvalidFormatException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } } if(isSetText){ run.setText(text, 0); } } } } } } /** * 依據圖片類型獲得對應的圖片類型代碼 * @param picType * @return */ public static int getPictureType(String picType){ int res = CustomXWPFDocument.PICTURE_TYPE_PICT; if(picType!=null){ if(picType.equalsIgnoreCase("png")){ res=CustomXWPFDocument.PICTURE_TYPE_PNG; }else if(picType.equalsIgnoreCase("dib")){ res = CustomXWPFDocument.PICTURE_TYPE_DIB; }else if(picType.equalsIgnoreCase("emf")){ res = CustomXWPFDocument.PICTURE_TYPE_EMF; }else if(picType.equalsIgnoreCase("jpg") || picType.equalsIgnoreCase("jpeg")){ res = CustomXWPFDocument.PICTURE_TYPE_JPEG; }else if(picType.equalsIgnoreCase("wmf")){ res = CustomXWPFDocument.PICTURE_TYPE_WMF; } } return res; } }
public class TestPoi { public static void main(String[] args) throws IOException { Map<String, Object> param=new HashMap<String, Object>(); param.put("${name}", "Joanna.Yan"); param.put("${examNum}", "000000000001"); param.put("${IDCard}", "111111111111111111"); param.put("${carModel}", "C1"); CustomXWPFDocument doc=WordUtil.generateWord(param, "D:\\joanna.docx"); FileOutputStream fopts = new FileOutputStream("D:\\yan.docx"); doc.write(fopts); fopts.close(); } }
以上就是本文的全體內容,願望對年夜家的進修有所贊助,也願望年夜家多多支撐。