亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Java多種方式動(dòng)態(tài)生成doc文檔

 更新時(shí)間:2016年09月10日 15:08:52   作者:Joanna.Yan  
這篇文章主要為大家詳細(xì)介紹了Java動(dòng)態(tài)生成doc文檔的多種方式,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

本來是要在Android端生成doc的(這需求...),最后方法沒有好的方法能夠在Android上做到完美,最后還是只能搬遷到服務(wù)器。不浪費(fèi),還是記錄下各框架不支持Android的原因以及他們的特點(diǎn)。Java相關(guān)的這類框架還是很多的,有幾個(gè)還不錯(cuò),可惜要么不支持Android,要么要收費(fèi)還價(jià)格不低。 

經(jīng)過親自測(cè)試,Android不支持Java的awt很多包不能直接在Android上用,F(xiàn)reeMarker挺不錯(cuò)的,能生成復(fù)雜漂亮的doc,可惜不支持Android。用POI在Android上能運(yùn)行,但是一路因?yàn)榘姹?,格式等走了很多坑,用WFS打開還是亂碼。Jword、Aspose.word能完美支持,Jword試用期只有30天兩者收費(fèi)都不菲。itext沒有測(cè)試,不過聽說也不支持Android。 

方法一:freemarker 

該方法需要先手動(dòng)創(chuàng)建一個(gè)doc模板(圖片記得使用占位符),并保存為xml文件。通過動(dòng)態(tài)替換特定標(biāo)簽${}中的內(nèi)容生成。example: 

先上效果圖:

public class DocUtil {
 public Configuration configure=null;
 
 public DocUtil(){
  configure=new Configuration(Configuration.VERSION_2_3_22);
  configure.setDefaultEncoding("utf-8");
 }
 /**
  * 根據(jù)Doc模板生成word文件
  * @param dataMap 需要填入模板的數(shù)據(jù)
  * @param downloadType 文件名稱
  * @param savePath 保存路徑
  */
 public void createDoc(Map<String,Object> dataMap,String downloadType,String savePath){
  try {
   //加載需要裝填的模板
   Template template=null;
   //設(shè)置模板裝置方法和路徑,F(xiàn)reeMarker支持多種模板裝載方法??梢灾豷ervlet,classpath,數(shù)據(jù)庫裝載。
   //加載模板文件,放在testDoc下
   configure.setClassForTemplateLoading(this.getClass(), "/testDoc");
   //設(shè)置對(duì)象包裝器
//   configure.setObjectWrapper(new DefaultObjectWrapper());
   //設(shè)置異常處理器
   configure.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER);
   //定義Template對(duì)象,注意模板類型名字與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", "測(cè)試駕校");
  dataMap.put("busyType", "初次申領(lǐng)");
  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號(hào)倒車入庫,車身出線 扣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 

補(bǔ)充關(guān)于動(dòng)態(tài)顯示list以及換行的問題 

需求明確到:在上面的扣分項(xiàng)中,如果我有幾條扣分項(xiàng),我希望每顯示一條換行。 

直接在要顯示的內(nèi)容上加換行符,并沒有什么效果,起不到換行的作用。 

其中在加ftl標(biāo)簽時(shí),如<#list></list>,就會(huì)出現(xiàn)一些問題,在xml中并不識(shí)別,導(dǎo)致項(xiàng)目不能運(yùn)行。 

解決: 

在需要顯示多條扣分項(xiàng)的位置加,并加換行符: 

<#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對(duì)象,注意模板類型名字與downloadType要一致
template=configure.getTemplate(downloadType+".ftl");此時(shí)xml文件會(huì)報(bào)錯(cuò),當(dāng)然也不能編譯運(yùn)行項(xiàng)目,需要將.xml文件改為.ftl文件保存。再編譯運(yùn)行,效果圖: 

方法二:POI 

用這個(gè)方法遇到了很多版本問題,這里是基于POI3.7+Word2007的,測(cè)試能夠完美運(yùn)行。 

你需要用Word2007手動(dòng)生成文檔模板(用其他的生成會(huì)報(bào)錯(cuò):無法打開文件),并用${}替換需要?jiǎng)討B(tài)更新的內(nèi)容,與上面類似,但是不需要你保存為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("測(cè)試");
 }
}

/**
 * 適用于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&&param.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&&paragraphList.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);
      }
     }
    }
   }
  }
 }
 
 /**
  * 根據(jù)圖片類型獲取對(duì)應(yīng)的圖片類型代碼
  * @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(); 
 }
}

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java中異常處理之try和catch代碼塊的使用

    Java中異常處理之try和catch代碼塊的使用

    這篇文章主要介紹了Java中異常處理之try和catch代碼塊的使用,是Java入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2015-09-09
  • 詳解Java中的四種引用類型(強(qiáng)軟弱虛)

    詳解Java中的四種引用類型(強(qiáng)軟弱虛)

    Java中的引用類型主要分為四種,分別是強(qiáng)引用、軟引用、弱引用和虛引用,這篇文章主要為大家詳細(xì)介紹了四者的使用與區(qū)別,需要的小伙伴可以參考下
    2023-10-10
  • logback的AsyncAppender高效日志處理方式源碼解析

    logback的AsyncAppender高效日志處理方式源碼解析

    這篇文章主要為大家介紹了logback的AsyncAppender高效日志處理方式源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-10-10
  • java使用RestTemplate封裝post請(qǐng)求方式

    java使用RestTemplate封裝post請(qǐng)求方式

    這篇文章主要介紹了java使用RestTemplate封裝post請(qǐng)求方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • IDEA教程之Activiti插件圖文詳解

    IDEA教程之Activiti插件圖文詳解

    這篇文章主要介紹了IDEA教程之Activiti插件圖文詳解,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-12-12
  • Java中stream的用法詳細(xì)解讀

    Java中stream的用法詳細(xì)解讀

    這篇文章主要介紹了Java中stream的用法詳細(xì)解讀,Stream 是 Java8 中處理集合的關(guān)鍵抽象概念,它可以指定你希望對(duì)集合進(jìn)行的操作,可以執(zhí)行非常復(fù)雜的查找、過濾和映射數(shù)據(jù)等操作,使用Stream API 對(duì)集合數(shù)據(jù)進(jìn)行操作,就類似于使用SQL執(zhí)行的數(shù)據(jù)庫查詢,需要的朋友可以參考下
    2023-10-10
  • SpringBoot獲取不到用戶真實(shí)IP的解決方法

    SpringBoot獲取不到用戶真實(shí)IP的解決方法

    最近遇到個(gè)問題,項(xiàng)目部署后發(fā)現(xiàn)服務(wù)端無法獲取到客戶端真實(shí)的IP地址,本文就來介紹一下這個(gè)問題的解決方法,感興趣的可以了解一下
    2023-08-08
  • Java?Redis配置Redisson的方法詳解

    Java?Redis配置Redisson的方法詳解

    這篇文章主要為大家詳細(xì)介紹了Java?Redis配置Redisson的相關(guān)資料,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)或工作有一定參考價(jià)值,感興趣的可以了解一下
    2022-08-08
  • 修改Android應(yīng)用的樣式的一些關(guān)鍵點(diǎn)解析

    修改Android應(yīng)用的樣式的一些關(guān)鍵點(diǎn)解析

    這篇文章主要介紹了修改Android應(yīng)用的樣式的一些關(guān)鍵點(diǎn),即對(duì)影響外觀的theme跟style的相關(guān)修改,需要的朋友可以參考下
    2015-12-12
  • JMagick實(shí)現(xiàn)基本圖像處理的類實(shí)例

    JMagick實(shí)現(xiàn)基本圖像處理的類實(shí)例

    這篇文章主要介紹了JMagick實(shí)現(xiàn)基本圖像處理的類,實(shí)例分析了java圖像處理的相關(guān)技巧,需要的朋友可以參考下
    2015-06-06

最新評(píng)論