2014-07-07 2 views
0

데이터베이스에서 html 데이터를 가져오고있었습니다. XSSFRichTexString 및 Jsoup를 통한 Apache POI Excel 텍스트 서식

<ul> 
    <li> <strong>Iam Bold </strong> <u><span style="color:Red">Iam Red Colored and Underlined</span> </u> </li> 
    <li> Just a Normal Text </li> 
    <li> Iam <b> Bold </b> <i><span style="color:Green"> and italic with colored </span></i> <u> and underlined </u> </li> 
    </ul> 

지금 같은 서식을 내 엑셀 출력에있을 것입니다 : 아래는 예입니다. 엑셀 출력에 대해서는 아래 이미지를 참조하십시오.

enter image description here

나는 Jsoup를 사용하여, 위의 HTML을 구문 분석 할 수 및 XSSFRichTextString를 사용하여, 당신은 xssfcell에서 서식있는 텍스트를 표시 할 수 있습니다 것을 알고있다. 또한 글 머리 기호 문자를 사용하여 글 머리 기호 아이콘을 얻을 수 있습니다.

하지만 전체 텍스트가 출력에 필요합니다. 그러나 정확한 결과물을 얻으려면 정확히 어떻게해야할지 모르는 경우가 있습니다.

XSSFRichTextString을 사용하여이를 수행하는 방법은 무엇입니까? 제발 도와주세요

+0

, 말, 나는 Excel에서 어떤 셀에 설정해야 할 값이 될 수있는 일 일반 boldItalicsallThree 일반 내부에 무엇이든간에 기울임 꼴 텍스트은 기울임 꼴로 설정해야합니다. 굵은 글씨은 굵은 글씨로 설정해야합니다. 밑줄이 그어진 텍스트은 밑줄로 설정해야합니다. – LazyGuy

+0

여기서 큰 도움이되지 않을 수 있습니다. 마크 업을 해석하고 필요한 객체를 생성하기 위해 파서를 작성해야합니다. 그것은 까다로울 것입니다. 글꼴이 색인에 적용되므로 태그 위치 주변에서 많이 재생해야합니다. ''와 같은 스타일 태그도 훨씬 더 복잡합니다. –

+0

Okie .. 떠나는 스팬 스타일, 다른 태그에 관한 도움 – LazyGuy

답변

2

내가 말한 것처럼 이것은 까다로운 임 플레멘 테이션이 될 것입니다. html 마크 업을 수집하고 글꼴로 적용하려면 파서를 만들어야합니다. 아래의 프로그램은 파서를 시작하는 데 사용할 수 있습니다. 그것은 html을 파싱하기 위해 jericho 파서를 사용하며 제한된 글꼴 지원을 가지고 있습니다. 그러나 그것은 당신이 제공 한 html을 처리합니다 (훨씬 더 좋은 방법으로 이것을 구현할 수도 있습니다). 또한 스트라이크 스루, 폰트 크기 등과 같은 추가적인 폰트 지원을 위해이 기능을 확장 할 수 있습니다. 다양한 글꼴 임 플리 멘 테이션을 위해 Google을 사용할 수 있습니다. 희망이 도움이됩니다. 이탤릭체와 같은 짧은에서

import java.io.File; 
import java.io.FileNotFoundException; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.util.ArrayList; 
import java.util.LinkedHashMap; 
import java.util.List; 
import java.util.Map; 
import java.util.Map.Entry; 
import java.util.Stack; 
import java.util.regex.Matcher; 
import java.util.regex.Pattern; 

import net.htmlparser.jericho.Element; 
import net.htmlparser.jericho.Source; 

import org.apache.commons.lang3.StringUtils; 
import org.apache.poi.hssf.usermodel.HSSFCellStyle; 
import org.apache.poi.hssf.usermodel.HSSFFont; 
import org.apache.poi.hssf.usermodel.HSSFPalette; 
import org.apache.poi.hssf.usermodel.HSSFRichTextString; 
import org.apache.poi.hssf.usermodel.HSSFSheet; 
import org.apache.poi.hssf.usermodel.HSSFWorkbook; 
import org.apache.poi.hssf.util.HSSFColor; 
import org.apache.poi.ss.usermodel.Cell; 
import org.apache.poi.ss.usermodel.Font; 
import org.apache.poi.ss.usermodel.Row; 

public class HtmlToExcel { 

    private static final int START_TAG = 0; 
    private static final int END_TAG = 1; 
    private static final char BULLET_CHARACTER = '\u2022'; 
    private static final String NEW_LINE = System.getProperty("line.separator"); 

    public static void main(String[] args) { 
     String html = "<ul>" 
       + "<li><em><strong>Bold Non-Colored + <span style=\"color: #FF0000\">Bolded and Colored Text</span></strong> </em> + Non font trailing<br/></li>" 
       + "<li>No Styling...Just a Text</li>" 
       + "<li><u><b>Bolded </b> and <i>Italic </i> and Underlined Text</u></li>" 
       + "<li><u>Underline Started and <span style=\"color: #00FF00\">Only Colored Text</span> Underline Ended</u></li>" 
       + "</ul>"; 

     HSSFWorkbook workBook = new HSSFWorkbook(); 
     HSSFSheet sheet = workBook.createSheet("Html Text"); 

     Source source = new Source(html); 
     int cellNo = 0; 
     for (Element ul : source.getAllElements("ul")) { 
      List<RichTextDetails> cellValues = new ArrayList<HtmlToExcel.RichTextDetails>(); 
      for (Element li : ul.getAllElements("li")) { 
       cellValues.add(createCellValue(li.toString(), workBook)); 
      } 
      createCell(cellValues, workBook, sheet, cellNo++); 
     } 

     FileOutputStream out = null; 
     try { 
      out = new FileOutputStream(new File("C:\\new.xls")); 
      workBook.write(out); 
     } catch (FileNotFoundException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } finally { 
      if (out != null) { 
       try { 
        out.close(); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } 
      } 
     } 
     System.out.println("Done"); 
    } 

    private static void createCell(List<RichTextDetails> cellValues, 
      HSSFWorkbook workBook, HSSFSheet sheet, int cellNo) { 
     HSSFRichTextString cellValue = mergeTextDetails(cellValues); 
     HSSFCellStyle wrapStyle = workBook.createCellStyle(); 
     wrapStyle.setWrapText(true); 
     Row row = sheet.createRow(cellNo); 
     Cell cell = row.createCell(0); 
     cell.setCellValue(cellValue); 
    } 

    private static HSSFRichTextString mergeTextDetails(
      List<RichTextDetails> cellValues) { 
     StringBuilder textBuffer = new StringBuilder(); 
     Map<Integer, HSSFFont> mergedMap = new LinkedHashMap<Integer, HSSFFont>(); 
     int currentIndex = 0; 
     for(RichTextDetails richTextDetail : cellValues){ 
      textBuffer.append(BULLET_CHARACTER + " "); 
      currentIndex = textBuffer.length(); 
      for (Entry<Integer, HSSFFont> entry : richTextDetail.getFontMap().entrySet()) { 
      mergedMap.put(entry.getKey() + currentIndex, entry.getValue()); 
     } 
      textBuffer.append(richTextDetail.getRichText()).append(NEW_LINE); 
     } 

     HSSFRichTextString richText = new HSSFRichTextString(textBuffer.toString()); 
    for (int i = 0; i < textBuffer.length(); i++) { 
     HSSFFont currentFont = mergedMap.get(i); 
     if (currentFont != null) { 
     richText.applyFont(i, i + 1, currentFont); 
     } 
    } 
     return richText; 
    } 

    private static RichTextDetails createCellValue(String html, HSSFWorkbook workBook) { 
     Source source = new Source(html); 
     Map<String, TagInfo> tagMap = new LinkedHashMap<String, HtmlToExcel.TagInfo>(); 
     for (Element e : source.getChildElements()) { 
      getInfo(e, tagMap); 
     } 

     String patternString = "(" + StringUtils.join(tagMap.keySet(), "|") + ")"; 
     Pattern pattern = Pattern.compile(patternString); 
     Matcher matcher = pattern.matcher(html); 

     StringBuffer textBuffer = new StringBuffer(); 
     List<RichTextInfo> textInfos = new ArrayList<HtmlToExcel.RichTextInfo>(); 
     Stack<RichTextInfo> richTextBuffer = new Stack<HtmlToExcel.RichTextInfo>(); 
     while (matcher.find()) { 
      matcher.appendReplacement(textBuffer, ""); 
      TagInfo currentTag = tagMap.get(matcher.group(1)); 
      if (START_TAG == currentTag.getTagType()) { 
       richTextBuffer.push(getRichTextInfo(currentTag, textBuffer.length(), workBook)); 
      } else { 
       if (!richTextBuffer.isEmpty()) { 
        RichTextInfo info = richTextBuffer.pop(); 
        if (info != null) { 
         info.setEndIndex(textBuffer.length()); 
         textInfos.add(info); 
        } 
       } 
      } 
     } 
     matcher.appendTail(textBuffer); 
     Map<Integer, HSSFFont> fontMap = buildFontMap(textInfos, workBook); 

     return new RichTextDetails(textBuffer.toString(), fontMap); 
    } 

    private static Map<Integer, HSSFFont> buildFontMap(
      List<RichTextInfo> textInfos, HSSFWorkbook workBook) { 
     Map<Integer, HSSFFont> fontMap = new LinkedHashMap<Integer, HSSFFont>(); 

     for (RichTextInfo richTextInfo : textInfos) { 
      if (richTextInfo.isValid()) { 
       for (int i = richTextInfo.getStartIndex(); i < richTextInfo.getEndIndex(); i++) { 
        fontMap.put(i, mergeFont(fontMap.get(i), richTextInfo.getFontStyle(), richTextInfo.getFontValue(), workBook)); 
       } 
      } 
     } 

     return fontMap; 
    } 

    private static HSSFFont mergeFont(HSSFFont font, STYLES fontStyle, 
      String fontValue, HSSFWorkbook workBook) { 
     if (font == null) { 
      font = workBook.createFont(); 
     } 

     switch (fontStyle) { 
      case BOLD: 
      case EM: 
      case STRONG: 
       font.setBoldweight(Font.BOLDWEIGHT_BOLD); 
       break; 
      case UNDERLINE: 
       font.setUnderline(HSSFFont.U_SINGLE); 
       break; 
      case ITALLICS: 
       font.setItalic(true); 
       break; 
      case COLOR: 
       if (!isEmpty(fontValue)) { 
        HSSFPalette palette = workBook.getCustomPalette(); 
        HSSFColor myColor = palette.findSimilarColor(
          Integer.valueOf(fontValue.substring(2, 4), 16), 
          Integer.valueOf(fontValue.substring(4, 6), 16), 
          Integer.valueOf(fontValue.substring(6, 8), 16)); 
        font.setColor(myColor.getIndex()); 
       } 
       break; 
      default: 
       break; 
     } 

     return font; 
    } 

    private static RichTextInfo getRichTextInfo(TagInfo currentTag, 
      int startIndex, HSSFWorkbook workBook) { 
     RichTextInfo info = null; 
     switch (STYLES.fromValue(currentTag.getTagName())) { 
      case SPAN: 
       if (!isEmpty(currentTag.getStyle())) { 
        for (String style : currentTag.getStyle().split(";")) { 
         String[] styleDetails = style.split(":"); 
         if (styleDetails != null && styleDetails.length > 1) { 
          if ("COLOR".equalsIgnoreCase(styleDetails[0].trim())) { 
           info = new RichTextInfo(startIndex, -1, STYLES.COLOR, styleDetails[1]); 
          } 
         } 
        } 
       } 
       break; 
      default: 
       info = new RichTextInfo(startIndex, -1, STYLES.fromValue(currentTag.getTagName())); 
       break; 
     } 
     return info; 
    } 

    private static boolean isEmpty(String str) { 
     return (str == null || str.trim().length() == 0); 
    } 

    private static void getInfo(Element e, Map<String, HtmlToExcel.TagInfo> tagMap) { 
     tagMap.put(e.getStartTag().toString(), new TagInfo(e.getStartTag().getName(), e.getAttributeValue("style"), START_TAG)); 
     if (e.getChildElements().size() > 0) { 
      List<Element> children = e.getChildElements(); 
      for (Element child : children){ 
       getInfo(child, tagMap); 
      } 
     } 
     if (e.getEndTag() != null) { 
      tagMap.put(e.getEndTag().toString(), new TagInfo(e.getEndTag().getName(), END_TAG)); 
     } else { 
      // Handling self closing tags 
      tagMap.put(e.getStartTag().toString(), new TagInfo(e.getStartTag().getName(), END_TAG)); 
     } 
    } 

    static class RichTextInfo { 
     private int startIndex; 
     private int endIndex; 
     private STYLES fontStyle; 
     private String fontValue; 

     public RichTextInfo(int startIndex, int endIndex, STYLES fontStyle) { 
      this.startIndex = startIndex; 
      this.endIndex = endIndex; 
      this.fontStyle = fontStyle; 
     } 

     public RichTextInfo(int startIndex, int endIndex, STYLES fontStyle, 
       String fontValue) { 
      this.startIndex = startIndex; 
      this.endIndex = endIndex; 
      this.fontStyle = fontStyle; 
      this.fontValue = fontValue; 
     } 

     public int getStartIndex() { 
      return startIndex; 
     } 

     public void setStartIndex(int startIndex) { 
      this.startIndex = startIndex; 
     } 

     public int getEndIndex() { 
      return endIndex; 
     } 

     public void setEndIndex(int endIndex) { 
      this.endIndex = endIndex; 
     } 

     public STYLES getFontStyle() { 
      return fontStyle; 
     } 

     public void setFontStyle(STYLES fontStyle) { 
      this.fontStyle = fontStyle; 
     } 

     public String getFontValue() { 
      return fontValue; 
     } 

     public void setFontValue(String fontValue) { 
      this.fontValue = fontValue; 
     } 

     public boolean isValid() { 
      return (startIndex != -1 && endIndex != -1 && endIndex >= startIndex); 
     } 

     @Override 
     public String toString() { 
      return "RichTextInfo [startIndex=" + startIndex + ", endIndex=" 
        + endIndex + ", fontStyle=" + fontStyle + ", fontValue=" 
        + fontValue + "]"; 
     } 
    } 

    static class RichTextDetails { 
     private String richText; 
     private Map<Integer, HSSFFont> fontMap; 

     public RichTextDetails(String richText, 
       Map<Integer, HSSFFont> fontMap) { 
      this.richText = richText; 
      this.fontMap = fontMap; 
     } 

     public String getRichText() { 
      return richText; 
     } 
     public void setRichText(String richText) { 
      this.richText = richText; 
     } 
     public Map<Integer, HSSFFont> getFontMap() { 
      return fontMap; 
     } 
     public void setFontMap(Map<Integer, HSSFFont> fontMap) { 
      this.fontMap = fontMap; 
     } 
    } 

    static class TagInfo { 
     private String tagName; 
     private String style; 
     private int tagType; 

     public TagInfo(String tagName, String style, int tagType) { 
      this.tagName = tagName; 
      this.style = style; 
      this.tagType = tagType; 
     } 

     public TagInfo(String tagName, int tagType) { 
      this.tagName = tagName; 
      this.tagType = tagType; 
     } 

     public String getTagName() { 
      return tagName; 
     } 

     public void setTagName(String tagName) { 
      this.tagName = tagName; 
     } 

     public int getTagType() { 
      return tagType; 
     } 

     public void setTagType(int tagType) { 
      this.tagType = tagType; 
     } 

     public String getStyle() { 
      return style; 
     } 

     public void setStyle(String style) { 
      this.style = style; 
     } 

     @Override 
     public String toString() { 
      return "TagInfo [tagName=" + tagName + ", style=" + style 
        + ", tagType=" + tagType + "]"; 
     } 
    } 

    enum STYLES { 
     BOLD("b"), 
     EM("em"), 
     STRONG("strong"), 
     COLOR("color"), 
     UNDERLINE("u"), 
     SPAN("span"), 
     ITALLICS("i"), 
     UNKNOWN("unknown"); 

     private String type; 

     private STYLES(String type) { 
      this.type = type; 
     } 

     public String getType() { 
      return type; 
     } 

     public static STYLES fromValue(String type) { 
      for (STYLES style : values()) { 
       if (style.type.equalsIgnoreCase(type)) { 
        return style; 
       } 
      } 
      return UNKNOWN; 
     } 
    } 
} 
+0

먼저 큰 시간을 보내고 답을주는 것에 감사드립니다. 위의 프로그램을 실행했지만 정확한 출력을 제공하지만 총알이없는 항목은 제공하지 않습니다. 난 그냥 HTML과 같은 접근 방식이 있는지 여부를 알고 싶다 - 우리가 html 태그 태그를 전달하여 형식화 된 출력을 렌더링하도록하면. 나는이 링크를 통해 갔다. didnt는 정확하게 계속하고있는 것을 이해한다. – LazyGuy

+0

또한 excel에서 aspose 또는 itext jars를 사용하여 위와 동일한 형식의 출력을 수행 할 수 있습니다. 그래서 우리 자신의 파싱 로직을 줄일 수 있습니다. – LazyGuy

+0

api가 없거나 html 마크 업을 거치지 않으면 더 많은 도움이 필요합니다. 난 그냥 글 머리 기호와 굵게, 이탤릭체 및 밑줄 만 사용하여 답변을 업데이트하고 싶습니다. 색상 포맷팅 필요 없음 ... 고맙습니다. – LazyGuy