国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > Java > 正文

Java多種方式動態生成doc文檔

2019-11-26 13:50:56
字體:
來源:轉載
供稿:網友

本來是要在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();  }}

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 凤城市| 化州市| 集贤县| 台湾省| 涿鹿县| 亳州市| 凌源市| 岑巩县| 鸡泽县| 土默特右旗| 华阴市| 井陉县| 台湾省| 德昌县| 岑溪市| 博爱县| 嘉善县| 铅山县| 揭阳市| 滕州市| 曲靖市| 池州市| 竹溪县| 兴城市| 依安县| 栖霞市| 景德镇市| 汤阴县| 永胜县| 武冈市| 汝城县| 奉贤区| 德兴市| 海兴县| 织金县| 闵行区| 崇阳县| 广丰县| 蒙城县| 平度市| 宁武县|