Java tutorial
/* * Copyright 2014-2015 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.deepoove.poi.resolver; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.ImmutablePair; import org.apache.commons.lang3.tuple.Pair; import org.apache.poi.xwpf.usermodel.XWPFFooter; import org.apache.poi.xwpf.usermodel.XWPFHeader; import org.apache.poi.xwpf.usermodel.XWPFParagraph; import org.apache.poi.xwpf.usermodel.XWPFRun; import org.apache.poi.xwpf.usermodel.XWPFTable; import org.apache.poi.xwpf.usermodel.XWPFTableCell; import org.apache.poi.xwpf.usermodel.XWPFTableRow; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.deepoove.poi.NiceXWPFDocument; import com.deepoove.poi.template.ElementTemplate; import com.deepoove.poi.template.cell.CellTemplate; import com.deepoove.poi.template.run.RunTemplate; /** * @author Sayi * @version 0.0.1 */ public class TemplateResolver { private static final Logger logger = LoggerFactory.getLogger(TemplateResolver.class); public static final String RULER_REGEX = "\\{\\{(#|@)?\\w+\\}\\}"; public static final String EXTRA_REGEX = "(\\{\\{)|(\\}\\})"; public static Pattern tagPattern = Pattern.compile(RULER_REGEX); public static Pattern varPattern = Pattern.compile(EXTRA_REGEX); public static List<ElementTemplate> parseElementTemplates(NiceXWPFDocument doc) { if (null == doc) return null; List<ElementTemplate> rts = new ArrayList<ElementTemplate>(); rts.addAll(parseParagraph(doc.getParagraphs())); rts.addAll(parseTable(doc.getTables())); List<XWPFHeader> headers = doc.getHeaderList(); if (null != headers) { for (XWPFHeader header : headers) { rts.addAll(parseParagraph(header.getParagraphs())); rts.addAll(parseTable(header.getTables())); } } List<XWPFFooter> footers = doc.getFooterList(); if (null != footers) { for (XWPFFooter footer : footers) { rts.addAll(parseParagraph(footer.getParagraphs())); rts.addAll(parseTable(footer.getTables())); } } return rts; } private static List<RunTemplate> parseParagraph(List<XWPFParagraph> paragraphs) { List<RunTemplate> result = new ArrayList<RunTemplate>(); if (null != paragraphs) { for (XWPFParagraph paragraph : paragraphs) { List<RunTemplate> parseRun = parseRun(paragraph); if (null != parseRun) result.addAll(parseRun); } } return result; } private static List<ElementTemplate> parseTable(List<XWPFTable> tables) { List<ElementTemplate> result = new ArrayList<ElementTemplate>(); if (null != tables && !tables.isEmpty()) { for (XWPFTable tb : tables) { List<ElementTemplate> parseTable = parseTable(tb); if (null != parseTable) result.addAll(parseTable); } } return result; } @SuppressWarnings("unused") private static CellTemplate parseCell(XWPFTableCell cell) { if (null == cell) return null; String text = cell.getText(); if (null == text || "".equals(text.trim())) { return null; } return (CellTemplate) parseTemplateFactory(text, cell); } public static List<ElementTemplate> parseTable(XWPFTable table) { if (null == table) return null; List<ElementTemplate> rts = new ArrayList<ElementTemplate>(); List<XWPFTableRow> rows = table.getRows(); if (null != rows) { for (XWPFTableRow row : rows) { List<XWPFTableCell> cells = row.getTableCells(); if (null != cells) { for (XWPFTableCell cell : cells) { // cell? // CellTemplate parseCell = parseCell(cell); // if (null != parseCell) { // rts.add(parseCell); // } else { rts.addAll(parseParagraph(cell.getParagraphs())); rts.addAll(parseTable(cell.getTables())); } } } } return rts; } /** * running string Algorithm * * @param paragraph * @return */ public static List<RunTemplate> parseRun(XWPFParagraph paragraph) { List<XWPFRun> runs = paragraph.getRuns(); if (null == runs || runs.isEmpty()) return null; String text = paragraph.getText(); logger.debug("Paragrah's text is:" + text); List<Pair<RunEdge, RunEdge>> pairs = new ArrayList<Pair<RunEdge, RunEdge>>(); List<String> tags = new ArrayList<String>(); calcTagPosInParagraph(text, pairs, tags); List<RunTemplate> rts = new ArrayList<RunTemplate>(); if (pairs.isEmpty()) return rts; RunTemplate runTemplate; calcRunPosInParagraph(runs, pairs); for (Pair<RunEdge, RunEdge> pai : pairs) { logger.debug(pai.getLeft().toString()); logger.debug(pai.getRight().toString()); } // split and merge Pair<RunEdge, RunEdge> pair2 = pairs.get(0); int length = pairs.size(); int tagIndex = length; for (int n = length - 1; n >= 0; n--) { pair2 = pairs.get(n); RunEdge left2 = pair2.getLeft(); RunEdge right2 = pair2.getRight(); int left_r = left2.getRunPos(); int right_r = right2.getRunPos(); int runEdge = left2.getRunEdge(); int runEdge2 = right2.getRunEdge(); String text1 = runs.get(left_r).getText(0); String text2 = runs.get(right_r).getText(0); if (runEdge2 + 1 >= text2.length()) { if (left_r != right_r) paragraph.removeRun(right_r); } else { String substring = text2.substring(runEdge2 + 1, text2.length()); if (left_r == right_r) { XWPFRun insertNewRun = paragraph.insertNewRun(right_r + 1); styleRun(insertNewRun, runs.get(right_r)); insertNewRun.setText(substring, 0); } else runs.get(right_r).setText(substring, 0); } for (int m = right_r - 1; m > left_r; m--) { paragraph.removeRun(m); } if (runEdge <= 0) { runs.get(left_r).setText(tags.get(--tagIndex), 0); runTemplate = parseRun(runs.get(left_r)); } else { String substring = text1.substring(0, runEdge); XWPFRun xwpfRun = runs.get(left_r); runs.get(left_r).setText(substring, 0); XWPFRun insertNewRun = paragraph.insertNewRun(left_r + 1); styleRun(insertNewRun, xwpfRun); insertNewRun.setText(tags.get(--tagIndex), 0); runTemplate = parseRun(runs.get(left_r + 1)); } if (null != runTemplate) { rts.add(runTemplate); } } return rts; } private static void calcRunPosInParagraph(List<XWPFRun> runs, List<Pair<RunEdge, RunEdge>> pairs) { int size = runs.size(), pos = 0, calc = 0; Pair<RunEdge, RunEdge> pair = pairs.get(pos); RunEdge leftEdge = pair.getLeft(); RunEdge rightEdge = pair.getRight(); int leftInAll = leftEdge.getAllPos(); int rightInAll = rightEdge.getAllPos(); for (int i = 0; i < size; i++) { XWPFRun run = runs.get(i); String str = run.getText(0); if (null == str) { logger.warn("found the empty text run,may be produce bug:" + run); calc += run.toString().length(); continue; } logger.debug(str); if (str.length() + calc < leftInAll) { calc += str.length(); continue; } for (int j = 0; j < str.length(); j++) { if (calc + j == leftInAll) { leftEdge.setRunPos(i); leftEdge.setRunEdge(j); leftEdge.setText(str); } if (calc + j == rightInAll - 1) { rightEdge.setRunPos(i); rightEdge.setRunEdge(j); rightEdge.setText(str); if (pos == pairs.size() - 1) break; pair = pairs.get(++pos); leftEdge = pair.getLeft(); rightEdge = pair.getRight(); leftInAll = leftEdge.getAllPos(); rightInAll = rightEdge.getAllPos(); } } calc += str.length(); } } private static void calcTagPosInParagraph(String text, List<Pair<RunEdge, RunEdge>> pairs, List<String> tags) { String group = null; int start = 0, end = 0; Matcher matcher = tagPattern.matcher(text); while (matcher.find()) { group = matcher.group(); tags.add(group); start = text.indexOf(group, end); end = start + group.length(); pairs.add(new ImmutablePair<RunEdge, RunEdge>(new RunEdge(start, group), new RunEdge(end, group))); } } private static void styleRun(XWPFRun destRun, XWPFRun srcRun) { if (null == destRun || null == srcRun) return; destRun.setBold(srcRun.isBold()); destRun.setColor(srcRun.getColor()); destRun.setFontFamily(srcRun.getFontFamily()); int fontSize = srcRun.getFontSize(); if (-1 != fontSize) destRun.setFontSize(fontSize); destRun.setItalic(srcRun.isItalic()); destRun.setStrike(srcRun.isStrike()); destRun.setUnderline(srcRun.getUnderline()); } public static RunTemplate parseRun(XWPFRun run) { String text = null; if (null == run || StringUtils.isBlank(text = run.getText(0))) return null; return (RunTemplate) parseTemplateFactory(text, run); } private static <T> ElementTemplate parseTemplateFactory(String text, T obj) { logger.debug("parse text:" + text); // temp ,future need to word analyze if (tagPattern.matcher(text).matches()) { String tag = varPattern.matcher(text).replaceAll("").trim(); GramerSymbol parseGramer = parseGramer(tag); String parseTagName = parseTagName(tag); if (obj.getClass() == XWPFRun.class) return RunTemplate.createRunTemplate(parseGramer, parseTagName, (XWPFRun) obj); else if (obj.getClass() == XWPFTableCell.class) return CellTemplate.create(parseGramer, parseTagName, (XWPFTableCell) obj); } return null; } // private static void parseTextBox(){ // try { // System.out.println(paragraph.getElementType()); // CTP ctp = paragraph.getCTP(); // CTR[] rArray = ctp.getRArray(); // System.out.println("size" + rArray.length); // XmlObject object = ctp.getRArray(0); // System.out.println(object.xmlText()); // XmlCursor cursor = object.newCursor(); // } catch (Exception e) { // // TODO Auto-generated catch block // e.printStackTrace(); // } // } public static GramerSymbol parseGramer(String tag) { char symbol = tag.charAt(0); switch (symbol) { case '@': return GramerSymbol.IMAGE; case '#': return GramerSymbol.TABLE; default: return GramerSymbol.TEXT; } } public static String parseTagName(String tag) { if (parseGramer(tag) == GramerSymbol.TEXT) return tag; return tag.substring(1); } }