<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      POI生成WORD文檔

       

      POI生成WORD文檔

          POI為Java系處理office文檔的比較優秀的開源庫,其中對于Excel的處理最為優秀,文檔也寫的很詳細。不過很多網友都認為它在word文檔處理方面就遜色很多,不過對于我本次的完成文檔的生成我依然選擇了POI。添加微信回復POI邀請你加群

      需要完成功能

      1. 配置Word模板文件,包括表格
      2. 解析配置的Word文檔,返回配置的特殊標記
      3. 構造數據,替換配置的標簽,以及生成表格

      配置word模版

      采用${xx}方式配置標簽,如果是表格在對應一行一列配置表格名稱

      注意在word文檔中,如果兩個相近的字符樣式不同,word默認會保存在不同的RUN元素中,由此很多朋友在配置好以后都需要保存為一個單獨的文件,然后不把不在一起的標簽合并到一個RUN元素中,如果文件比較大,我相信這絕對是一個比較痛苦的事情,這里將會側重處理這個問題.我的解決方案是只保留第一RUN的樣式其他的刪掉

      解析word模板

      首先需要將文件轉換為XWPFDocument對象,可以通過流的當時,也可以通過opcpackage,不過如果使用opcpackage打開的方式,打開的文件和最終生成的文件不能夠是同一個文件,我這里采用文件流的方式

      public XWPFDocument openDocument() {
              XWPFDocument xdoc = null;
              InputStream is = null;
              try {
                  is = new FileInputStream(saveFile);
                  xdoc = new XWPFDocument(is);
              } catch (IOException e) {
                  e.printStackTrace();
              }
              return xdoc;
          }
      

      獲取非列表的標簽,實現方式XWPFDocument對象有當前所有段落以及表格,這里暫不考慮表格嵌套表格的情況,每個段落的文本信息是可以通過p.getText()獲取,獲取段落中文檔配置信息如下:

         // 獲取段落集合中所有文本
          public List<TagInfo> getWordTag(XWPFDocument doc, String regex) {
              List<TagInfo> tags = new ArrayList<TagInfo>();
              // 普通段落
              List<XWPFParagraph> pars = doc.getParagraphs();
              for (int i = 0; i < pars.size(); i++) {
                  XWPFParagraph p = pars.get(i);
                  setTagInfoList(tags, p, regex);
              }
              // Table中段落
              List<XWPFTable> commTables = getDocTables(doc, false, regex);
              for (XWPFTable table : commTables) {
                  List<XWPFParagraph> tparags = getTableParagraph(table);
                  for (int i = 0; i < tparags.size(); i++) {
                      XWPFParagraph p = tparags.get(i);
                      setTagInfoList(tags, p, regex);
                  }
              }
              return tags;
          }
      

      獲取文本后通過正則解析,并依次保存到TagInfo中

      // 向 taglist中添加新解析的段落信息
          private void setTagInfoList(List<TagInfo> list, XWPFParagraph p,
                  String regex) {
              if (regex == "")
                  regex = defaultRegex;
              Pattern pattern = Pattern.compile(regex);
              Matcher matcher = pattern.matcher(p.getText());
              int startPosition = 0;
              while (matcher.find(startPosition)) {
                  String match = matcher.group();
                  if (!list.contains(new TagInfo(match, match, ""))) {
                      list.add(new TagInfo(match, match, ""));
                  }
                  startPosition = matcher.end();
              }
          }
      

      解析表格

          // 獲取Table列表中的配置信息
          public Map<String, List<List<TagInfo>>> getTableTag(XWPFDocument doc,
                  String regex) {
              Map<String, List<List<TagInfo>>> mapList = new HashMap<String, List<List<TagInfo>>>();
              List<XWPFTable> lstTables = getDocTables(doc, true, regex);
              for (XWPFTable table : lstTables) {
                  // 獲取每個表格第一個單元格,以及最后一行
                  String strTableName = getTableListName(table, regex);
                  List<List<TagInfo>> list = new ArrayList<List<TagInfo>>();
                  List<TagInfo> lstTag = new ArrayList<TagInfo>();
                  int rowSize = table.getRows().size();
                  XWPFTableRow lastRow = table.getRow(rowSize - 1);
                  for (XWPFTableCell cell : lastRow.getTableCells()) {
                      for (XWPFParagraph p : cell.getParagraphs()) {
                          // 去掉空白字符串
                          if (p.getText() != null && p.getText().length() > 0) {
                              setTagInfoList(lstTag, p, regex);
                          }
                      }
                  }
                  list.add(lstTag);
                  // 添加到數據集
                  mapList.put(strTableName, list);
              }
              return mapList;
          }
      

      生成WORD文檔

      難點替換標簽
      傳入數據格式包含三個formtag以及一個tableTag

      {"formTags":
      [{"TagName":"${xxxx}","TagText":"${xxxx}","TagValue":""},
      {"TagName":"${123}","TagText":"${123}","TagValue":""},
      {"TagName":"${ddd}","TagText":"${ddd}","TagValue":""}],
      "tableTags":{
      "${table}":[
      [{"TagName":"${COL1}","TagText":"${COL1}","TagValue":""},{"TagName":"${COL2}","TagText":"${COL2}","TagValue":""}]
      ]}
      }

      普通文檔生成,并且保留配置樣式,這里主要使用POI中提供searchText方法,返回Tag所有所在的RUN標簽,通過一個字符做比較,如果找的第一個匹配的文本開始計數,所有在當前條件下類型 $${xxx}這樣的標簽是無法實現替換的
      替換普通文本Tag

          public void ReplaceInParagraph(List<TagInfo> tagList, XWPFParagraph para,
                  String regex) {
              if (regex == "")
                  regex = defaultRegex;
              List<XWPFRun> runs = para.getRuns();
              for (TagInfo ti : tagList) {
                  String find = ti.TagText;
                  String replValue = ti.TagValue;
                  TextSegement found = para.searchText(find,
                          new PositionInParagraph());
                  if (found != null) {
                      // 判斷查找內容是否在同一個Run標簽中
                      if (found.getBeginRun() == found.getEndRun()) {
                          XWPFRun run = runs.get(found.getBeginRun());
                          String runText = run.getText(run.getTextPosition());
                          String replaced = runText.replace(find, replValue);
                          run.setText(replaced, 0);
                      } else {
                          // 存在多個Run標簽
                          StringBuilder sb = new StringBuilder();
                          for (int runPos = found.getBeginRun(); runPos <= found
                                  .getEndRun(); runPos++) {
                              XWPFRun run = runs.get(runPos);
                              sb.append(run.getText((run.getTextPosition())));
                          }
                          String connectedRuns = sb.toString();
                          String replaced = connectedRuns.replace(find, replValue);
                          XWPFRun firstRun = runs.get(found.getBeginRun());
                          firstRun.setText(replaced, 0);
                          // 刪除后邊的run標簽
                          for (int runPos = found.getBeginRun() + 1; runPos <= found
                                  .getEndRun(); runPos++) {
                              // 清空其他標簽內容
                              XWPFRun partNext = runs.get(runPos);
                              partNext.setText("", 0);
                          }
                      }
                  }
              }
              // 完成第一遍查找,檢測段落中的標簽是否已經替換完
              Pattern pattern = Pattern.compile(regex);
              Matcher matcher = pattern.matcher(para.getText());
              boolean find = matcher.find();
              if (find) {
                  ReplaceInParagraph(tagList, para, regex);
                  find = false;
              }
          }
      

      表格主要是通過復制模版行,然后對模版行中的內容做修改
      復制文本標簽RUN

          private void CopyRun(XWPFRun target, XWPFRun source) {
              target.getCTR().setRPr(source.getCTR().getRPr());
              // 設置文本
              target.setText(source.text());
          }
      

      復制段落XWPFParagraph

          private void copyParagraph(XWPFParagraph target, XWPFParagraph source) {
              // 設置段落樣式
              target.getCTP().setPPr(source.getCTP().getPPr());
              // 添加Run標簽
              for (int pos = 0; pos < target.getRuns().size(); pos++) {
                  target.removeRun(pos);
              }
              for (XWPFRun s : source.getRuns()) {
                  XWPFRun targetrun = target.createRun();
                  CopyRun(targetrun, s);
              }
          }
      

      復制單元格XWPFTableCell

          private void copyTableCell(XWPFTableCell target, XWPFTableCell source) {
              // 列屬性
              target.getCTTc().setTcPr(source.getCTTc().getTcPr());
              // 刪除目標 targetCell 所有單元格
              for (int pos = 0; pos < target.getParagraphs().size(); pos++) {
                  target.removeParagraph(pos);
              }
              // 添加段落
              for (XWPFParagraph sp : source.getParagraphs()) {
                  XWPFParagraph targetP = target.addParagraph();
                  copyParagraph(targetP, sp);
              }
          }
      

      復制行XWPFTableRow

          private void CopytTableRow(XWPFTableRow target, XWPFTableRow source) {
              // 復制樣式
              target.getCtRow().setTrPr(source.getCtRow().getTrPr());
              // 復制單元格
              for (int i = 0; i < target.getTableCells().size(); i++) {
                  copyTableCell(target.getCell(i), source.getCell(i));
              }
          }

      以上就完成所有功能更,只要你配置規范,可以完全原樣輸出模版內容。這里特別感謝下肖哥哥大力支持。

      其次,java的編碼真的讓人很無語,get或post時中文各種亂碼

      posted @ 2016-06-03 17:11  _herbert  閱讀(40897)  評論(7)    收藏  舉報
      主站蜘蛛池模板: 国产精品人成视频免费播放| 久久精品国产亚洲av麻豆长发| 五月婷之久久综合丝袜美腿 | 18成人片黄网站www| 2020精品自拍视频曝光| 日韩精品久久久肉伦网站| 婷婷久久香蕉五月综合加勒比| 久久天天躁狠狠躁夜夜2020老熟妇| 色欲国产精品一区成人精品| 成av人电影在线观看| 国产一区二区三区日韩精品| 国内女人喷潮完整视频| 免费无码久久成人网站入口| 亚洲天堂伊人久久a成人| 国产AV一区二区三区| 18禁成人免费无码网站| 日韩精品卡一卡二卡三卡四| 国产极品视频一区二区三区| 东京热av无码电影一区二区| 中文字幕一区二区三区久久蜜桃 | 婷婷开心深爱五月天播播| 欧美激情一区二区三区成人| 亚洲性日韩精品一区二区| 国产网友愉拍精品视频手机| 女人被狂躁的高潮免费视频| 国产短视频精品一区二区| 99久久国产一区二区三区| 最近免费中文字幕mv在线视频3| 无码专区 人妻系列 在线| 美女人妻激情乱人伦| 成人无套少萝内射中出| 国产精品自拍中文字幕| 天堂av资源在线免费| 欧美精品V欧洲精品| 免费无码又爽又刺激高潮虎虎视频 | 成人福利一区二区视频在线| 色爱区综合激情五月激情| 欧美性群另类交| 国产亚洲人成网站在线观看| 久久热这里只有精品66| 大地资源中文在线观看西瓜|