OpenXML (C#) で *.docx ドキュメントを解析する際に 1 つの問題があります。
私の手順は次のとおり
です。 1. *.docx ドキュメントをロードします
。 2. 段落のリストを受け取ります。
3. 各段落で、text、image、および table 要素を探し
ます
。 htmlファイル
ドキュメント内の画像ファイルを見つけて抽出する方法を見つけました。ここで 1 つのステップがあります。テキスト (段落) 内の表の位置を見つけます。
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();
}
ここで、テーブルの場所をテキストで指定します (Word で表示されるように)。
最後の:
わかりました、皆さん、わかりました。私のサンプル関数には大きな間違いが 1 つあります。ドキュメント本文の段落要素を列挙しています。表は段落と同じレベルにあるため、関数は表を無視します。したがって、ドキュメント Body の Elements を列挙する必要があります。
docx から正しい HTML を生成するためのテスト関数を次に示します (これは単なるテスト コードであるため、きれいではありません)。
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);
}