2012-06-28 2 views
5

OpenXML (C#)을 사용하여 * .docx 문서를 구문 분석 할 때 한 가지 문제점이 있습니다.DOCX에서 테이블 추출

그래서, 여기에 내 단계입니다 : 단락의
1.로드 *의 .DOCX 문서
2. 받으십시오 목록
각 텍스트에 대한 텍스트, 이미지 및 테이블 요소에 대한 각 단락의 모습
4에서 (3)과 이미지 요소 HTML 태그 생성
5. 출력을 * .html 파일로 저장하십시오.

문서에서 이미지 파일을 찾고 추출하는 방법을 찾았습니다. 이제 한 가지 단계를 거쳐야합니다. 텍스트 (단락)에서 표 위치가 어디에 있는지 찾아보십시오.

OpenXML을 사용하여 * .docx 문서에서 테이블을 찾는 방법을 알고 있다면 도움을 받으십시오. 감사합니다. .

추가 : 좋아, 내가 무슨 뜻인지 설명하지 않을 수도 있습니다. 단락의 내용을 얻으면 쉴드 객체를 텍스트 블록, 그림 등으로 찾을 수 있습니다. 단락에 그림이 포함 된 실행이 포함되어 있으면 Word 문서의이 위치에 이미지가 놓여 있음을 의미합니다. 내 기능의

샘플 :

public static string ParseDocxDocument(string pathToFile) 
    { 
     StringBuilder result = new StringBuilder(); 
     WordprocessingDocument wordProcessingDoc = WordprocessingDocument.Open(pathToFile, true); 
     List<ImagePart> imgPart = wordProcessingDoc.MainDocumentPart.ImageParts.ToList(); 
     IEnumerable<Paragraph> paragraphElement = wordProcessingDoc.MainDocumentPart.Document.Descendants<Paragraph>(); 
     int imgCounter = 0; 


     foreach (Paragraph par in paragraphElement) 
     { 

       //Add new paragraph tag 
       result.Append("<div style=\"width:100%; text-align:"); 

       //Append anchor style 
       if (par.ParagraphProperties != null && par.ParagraphProperties.Justification != null) 
        switch (par.ParagraphProperties.Justification.Val.Value) 
        { 
         case JustificationValues.Left: 
          result.Append("left;"); 
          break; 
         case JustificationValues.Center: 
          result.Append("center;"); 
          break; 
         case JustificationValues.Both: 
          result.Append("justify;"); 
          break; 
         case JustificationValues.Right: 
         default: 
          result.Append("right;"); 
          break; 
        } 
       else 
        result.Append("left;"); 

       //Append text decoration style 
       if (par.ParagraphProperties != null && par.ParagraphProperties.ParagraphMarkRunProperties != null && par.ParagraphProperties.ParagraphMarkRunProperties.HasChildren) 
        foreach (OpenXmlElement chield in par.ParagraphProperties.ParagraphMarkRunProperties.ChildElements) 
        { 
         switch (chield.GetType().Name) 
         { 
          case "Bold": 
           result.Append("font-weight:bold;"); 
           break; 
          case "Underline": 
           result.Append("text-decoration:underline;"); 
           break; 
          case "Italic": 
           result.Append("font-style:italic;"); 
           break; 
          case "FontSize": 
           result.Append("font-size:" + ((FontSize)chield).Val.Value + "px;"); 
           break; 
          default: break; 
         } 
        } 

       result.Append("\">"); 

       //Add image tag 
       IEnumerable<Run> runs = par.Descendants<Run>(); 
       foreach (Run run in runs) 
       { 
        if (run.HasChildren) 
        { 
         foreach (OpenXmlElement chield in run.ChildElements.Where(o => o.GetType().Name == "Picture")) 
         { 
          result.Append(string.Format("<img style=\"{1}\" src=\"data:image/jpeg;base64,{0}\" />", GetBase64Image(imgPart[imgCounter].GetStream()), 
              ((DocumentFormat.OpenXml.Vml.Shape)chield.ChildElements.Where(o => o.GetType().Name == "Shape").FirstOrDefault()).Style 
           )); 
          imgCounter++; 
         } 
        } 
       } 

       //Append inner text 
       IEnumerable<Text> textElement = par.Descendants<Text>(); 
       if (par.Descendants<Text>().Count() == 0) 
        result.Append("<br />"); 

       foreach (Text t in textElement) 
       { 
        result.Append(t.Text); 
       } 


       result.Append("</div>"); 
       result.Append(Environment.NewLine); 

     } 

     wordProcessingDoc.Close(); 

     return result.ToString(); 
    } 

지금 나는 (이 말씀에 나타나는) 텍스트에서 테이블 위치를 지정 whant.

결승 :

모두들, 알아 냈습니다. 내 견본 기능에서 하나의 큰 실수. 문서 본문의 단락 요소를 열거합니다. 테이블은 단락과 동일한 수준이므로 함수는 테이블을 무시합니다. 그래서 우리는 문서 본문의 엘리먼트를 열거해야합니다.

여기

public static string ParseDocxDocument(string pathToFile) 
    { 
     StringBuilder result = new StringBuilder(); 
     WordprocessingDocument wordProcessingDoc = WordprocessingDocument.Open(pathToFile, true); 
     List<ImagePart> imgPart = wordProcessingDoc.MainDocumentPart.ImageParts.ToList(); 
     List<string> tableCellContent = new List<string>(); 
     IEnumerable<Paragraph> paragraphElement = wordProcessingDoc.MainDocumentPart.Document.Descendants<Paragraph>(); 
     int imgCounter = 0; 

     foreach (OpenXmlElement section in wordProcessingDoc.MainDocumentPart.Document.Body.Elements<OpenXmlElement>()) 
     { 
      if(section.GetType().Name == "Paragraph") 
      { 
       Paragraph par = (Paragraph)section; 
       //Add new paragraph tag 
       result.Append("<div style=\"width:100%; text-align:"); 

       //Append anchor style 
       if (par.ParagraphProperties != null && par.ParagraphProperties.Justification != null) 
        switch (par.ParagraphProperties.Justification.Val.Value) 
        { 
         case JustificationValues.Left: 
          result.Append("left;"); 
          break; 
         case JustificationValues.Center: 
          result.Append("center;"); 
          break; 
         case JustificationValues.Both: 
          result.Append("justify;"); 
          break; 
         case JustificationValues.Right: 
         default: 
          result.Append("right;"); 
          break; 
        } 
       else 
        result.Append("left;"); 

       //Append text decoration style 
       if (par.ParagraphProperties != null && par.ParagraphProperties.ParagraphMarkRunProperties != null && par.ParagraphProperties.ParagraphMarkRunProperties.HasChildren) 
        foreach (OpenXmlElement chield in par.ParagraphProperties.ParagraphMarkRunProperties.ChildElements) 
        { 
         switch (chield.GetType().Name) 
         { 
          case "Bold": 
           result.Append("font-weight:bold;"); 
           break; 
          case "Underline": 
           result.Append("text-decoration:underline;"); 
           break; 
          case "Italic": 
           result.Append("font-style:italic;"); 
           break; 
          case "FontSize": 
           result.Append("font-size:" + ((FontSize)chield).Val.Value + "px;"); 
           break; 
          default: break; 
         } 
        } 

       result.Append("\">"); 

       //Add image tag 
       IEnumerable<Run> runs = par.Descendants<Run>(); 
       foreach (Run run in runs) 
       { 
        if (run.HasChildren) 
        { 
         foreach (OpenXmlElement chield in run.ChildElements.Where(o => o.GetType().Name == "Picture")) 
         { 
          result.Append(string.Format("<img style=\"{1}\" src=\"data:image/jpeg;base64,{0}\" />", GetBase64Image(imgPart[imgCounter].GetStream()), 
              ((DocumentFormat.OpenXml.Vml.Shape)chield.ChildElements.Where(o => o.GetType().Name == "Shape").FirstOrDefault()).Style 
           )); 
          imgCounter++; 
         } 
         foreach (OpenXmlElement table in run.ChildElements.Where(o => o.GetType().Name == "Table")) 
         { 
          result.Append("<strong>HERE'S TABLE</strong>"); 
         } 
        } 
       } 

       //Append inner text 
       IEnumerable<Text> textElement = par.Descendants<Text>(); 
       if (par.Descendants<Text>().Count() == 0) 
        result.Append("<br />"); 

       foreach (Text t in textElement.Where(o=>!tableCellContent.Contains(o.Text.Trim()))) 
       { 
        result.Append(t.Text); 
       } 


       result.Append("</div>"); 
       result.Append(Environment.NewLine); 

      } 
      else if (section.GetType().Name=="Table") 
      { 
       result.Append("<table>"); 
       Table tab = (Table)section; 
       foreach (TableRow row in tab.Descendants<TableRow>()) 
       { 
        result.Append("<tr>"); 
        foreach (TableCell cell in row.Descendants<TableCell>()) 
        { 
         result.Append("<td>"); 
         result.Append(cell.InnerText); 
         tableCellContent.Add(cell.InnerText.Trim()); 
         result.Append("</td>"); 
        } 
        result.Append("</tr>"); 
       } 
       result.Append("</table>"); 
      }     
     } 


     wordProcessingDoc.Close(); 

     return result.ToString(); 
    } 

    private static string GetBase64Image(Stream inputData) 
    { 
     byte[] data = new byte[inputData.Length]; 
     inputData.Read(data, 0, data.Length); 
     return Convert.ToBase64String(data); 
    } 

답변

1

시도 문서에서 첫 번째 테이블을 찾기 위해 다음 (그냥 테스트 코드, 그래서 깨끗 아니다) DOCX에서 올바른 HTML을 생성하는 내 테스트 기능입니다.

Table table = doc.MainDocumentPart.Document.Body.Elements<Table>().First(); 
+0

테이블을 읽고 구문 분석하는 방법을 알고 있습니다. 내 질문은 tosition insite text를 찾는 방법입니다. – EkzoMan

+0

제 작업 코드를 추가했습니다. 귀하의 게시물은 올바른 방향으로 일하고 있습니다. 그래서 나는 당신의 대답을 정확하다고 표시합니다. – EkzoMan