Skip to content

Commit ceff7f1

Browse files
Added sample
1 parent a700e03 commit ceff7f1

6 files changed

Lines changed: 221 additions & 0 deletions

File tree

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio Version 17
4+
VisualStudioVersion = 17.14.36930.0 d17.14
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Extract-Table-to-DataTable", "Extract-Table-to-DataTable\Extract-Table-to-DataTable.csproj", "{109F9D9A-2486-6191-E3ED-B9C89550B0D4}"
7+
EndProject
8+
Global
9+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
10+
Debug|Any CPU = Debug|Any CPU
11+
Release|Any CPU = Release|Any CPU
12+
EndGlobalSection
13+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
14+
{109F9D9A-2486-6191-E3ED-B9C89550B0D4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15+
{109F9D9A-2486-6191-E3ED-B9C89550B0D4}.Debug|Any CPU.Build.0 = Debug|Any CPU
16+
{109F9D9A-2486-6191-E3ED-B9C89550B0D4}.Release|Any CPU.ActiveCfg = Release|Any CPU
17+
{109F9D9A-2486-6191-E3ED-B9C89550B0D4}.Release|Any CPU.Build.0 = Release|Any CPU
18+
EndGlobalSection
19+
GlobalSection(SolutionProperties) = preSolution
20+
HideSolutionNode = FALSE
21+
EndGlobalSection
22+
GlobalSection(ExtensibilityGlobals) = postSolution
23+
SolutionGuid = {8D7007A5-9202-4A9B-A8E2-50EAB025B312}
24+
EndGlobalSection
25+
EndGlobal
Binary file not shown.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net8.0</TargetFramework>
6+
<RootNamespace>Extract-Table-to-DataTable</RootNamespace>
7+
<ImplicitUsings>enable</ImplicitUsings>
8+
<Nullable>enable</Nullable>
9+
</PropertyGroup>
10+
11+
<ItemGroup>
12+
<PackageReference Include="Syncfusion.DocIO.Net.Core" Version="*" />
13+
<PackageReference Include="Syncfusion.XlsIO.Net.Core" Version="*" />
14+
</ItemGroup>
15+
16+
<ItemGroup>
17+
<None Update="Data\Input.docx">
18+
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
19+
</None>
20+
<None Update="Output\.gitkeep">
21+
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
22+
</None>
23+
</ItemGroup>
24+
</Project>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+

Binary file not shown.
Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
using System.Text;
2+
using Syncfusion.DocIO;
3+
using Syncfusion.DocIO.DLS;
4+
using Syncfusion.XlsIO;
5+
6+
class Program
7+
{
8+
static void Main(string[] args)
9+
{
10+
// Load existing word document
11+
using (FileStream inputfileStream = new FileStream(Path.GetFullPath(@"../../../Data/Input.docx"), FileMode.Open))
12+
{
13+
using (WordDocument document = new WordDocument(inputfileStream, FormatType.Automatic))
14+
{
15+
using (ExcelEngine engine = new ExcelEngine())
16+
{
17+
IApplication app = engine.Excel;
18+
app.DefaultVersion = ExcelVersion.Excel2016;
19+
20+
// Create one sheet to start with; we’ll add sheets as we find more tables.
21+
IWorkbook workbook = app.Workbooks.Create(1);
22+
int sheetIndex = 0;
23+
int tableNumber = 0;
24+
25+
// Get table entities in word document
26+
List<Entity> entities = document.FindAllItemsByProperty(EntityType.Table, null, null);
27+
28+
foreach (Entity entity in entities)
29+
{
30+
WTable wTable = (WTable)entity;
31+
32+
if (sheetIndex >= workbook.Worksheets.Count)
33+
workbook.Worksheets.Create();
34+
35+
IWorksheet worksheet = workbook.Worksheets[sheetIndex++];
36+
worksheet.Name = $"Table{++tableNumber}";
37+
38+
// Export with merges starting at row=1, col=1
39+
ExportWordTableToExcelMerged(wTable, worksheet, 1, 1);
40+
41+
// Formatting
42+
worksheet.UsedRange.AutofitRows();
43+
worksheet.UsedRange.AutofitColumns();
44+
}
45+
using (FileStream outputStream = new FileStream(Path.GetFullPath(@"../../../Output/Result.xlsx"), FileMode.Create))
46+
{
47+
workbook.SaveAs(outputStream);
48+
}
49+
workbook.Close();
50+
}
51+
}
52+
}
53+
}
54+
55+
/// <summary>
56+
/// Writes a Word table to the worksheet, preserving horizontal and vertical merges.
57+
/// startRow/startCol are 1-based Excel coordinates where the table should be placed.
58+
/// </summary>
59+
private static void ExportWordTableToExcelMerged(IWTable table, IWorksheet worksheet, int startRow, int startCol)
60+
{
61+
// Iterate table rows
62+
for (int r = 0; r < table.Rows.Count; r++)
63+
{
64+
WTableRow wRow = table.Rows[r];
65+
66+
// Map Word's logical grid to Excel columns using GridSpan
67+
int gridCol = startCol;
68+
69+
for (int i = 0; i < wRow.Cells.Count; i++)
70+
{
71+
WTableCell wCell = wRow.Cells[i];
72+
73+
// Horizontal width in grid columns
74+
int hSpan = Math.Max(1, (int)wCell.GridSpan);
75+
76+
// Merge flags (DocIO)
77+
CellMerge vFlag = wCell.CellFormat.VerticalMerge;
78+
CellMerge hFlag = wCell.CellFormat.HorizontalMerge;
79+
80+
// Excel start cell for this Word cell
81+
int xRow = startRow + r;
82+
int xCol = gridCol;
83+
84+
// Compute vertical span when this cell is the START of a vertical merge
85+
int vSpan = 1;
86+
if (vFlag == CellMerge.Start)
87+
{
88+
// Count how many subsequent rows continue the merge at the same grid column
89+
for (int nr = r + 1; nr < table.Rows.Count; nr++)
90+
{
91+
WTableRow nextRow = table.Rows[nr];
92+
WTableCell nextCell = GetCellAtGridColumn(nextRow, (xCol - startCol + 1));
93+
if (nextCell != null && nextCell.CellFormat.VerticalMerge == CellMerge.Continue)
94+
vSpan++;
95+
else
96+
break;
97+
}
98+
}
99+
100+
// Is Start or None of a merge region
101+
bool isStartorNone =
102+
(vFlag != CellMerge.Continue) &&
103+
(hFlag != CellMerge.Continue);
104+
105+
if (isStartorNone)
106+
{
107+
// To get the exact lest row and last column -1
108+
int lastRow = xRow + vSpan - 1;
109+
int lastCol = xCol + hSpan - 1;
110+
111+
// Merge in Excel if region spans multiple cells
112+
if (lastRow > xRow || lastCol > xCol)
113+
worksheet.Range[xRow, xCol, lastRow, lastCol].Merge(); // XlsIO merge
114+
115+
// Write the visible text to the top-left Excel cell
116+
IRange range = worksheet.Range[xRow, xCol];
117+
range.Text = BuildCellText(wCell);
118+
119+
// Text styling
120+
range.CellStyle.HorizontalAlignment = ExcelHAlign.HAlignCenter;
121+
range.CellStyle.VerticalAlignment = ExcelVAlign.VAlignCenter;
122+
// Border formatting
123+
worksheet.Range[xRow, xCol, lastRow, lastCol].CellStyle.Borders[ExcelBordersIndex.EdgeLeft].LineStyle = ExcelLineStyle.Thin;
124+
worksheet.Range[xRow, xCol, lastRow, lastCol].CellStyle.Borders[ExcelBordersIndex.EdgeRight].LineStyle = ExcelLineStyle.Thin;
125+
worksheet.Range[xRow, xCol, lastRow, lastCol].CellStyle.Borders[ExcelBordersIndex.EdgeTop].LineStyle = ExcelLineStyle.Thin;
126+
worksheet.Range[xRow, xCol, lastRow, lastCol].CellStyle.Borders[ExcelBordersIndex.EdgeBottom].LineStyle = ExcelLineStyle.Thin;
127+
}
128+
// Add Excel column cursor by the horizontal span of this Word cell
129+
gridCol += hSpan;
130+
}
131+
}
132+
}
133+
134+
/// <summary>
135+
/// Returns the WTableCell occupying the given 1-based "grid column" in this row,
136+
/// taking each cell's GridSpan into account.
137+
/// </summary>
138+
static WTableCell GetCellAtGridColumn(WTableRow row, int gridColumn)
139+
{
140+
int cursor = 1;
141+
foreach (WTableCell c in row.Cells)
142+
{
143+
int span = Math.Max((int)1, (int)c.GridSpan);
144+
int start = cursor;
145+
int end = cursor + span - 1;
146+
if (gridColumn >= start && gridColumn <= end)
147+
return c;
148+
cursor += span;
149+
}
150+
return null;
151+
}
152+
153+
/// <summary>
154+
/// Concatenate all paragraph texts in a Word cell (one per line).
155+
/// </summary>
156+
static string BuildCellText(WTableCell cell)
157+
{
158+
StringBuilder sb = new StringBuilder();
159+
for (int p = 0; p < cell.Paragraphs.Count; p++)
160+
{
161+
WParagraph para = (WParagraph)cell.Paragraphs[p];
162+
string text = para.Text?.TrimEnd();
163+
if (!string.IsNullOrEmpty(text))
164+
{
165+
if (sb.Length > 0) sb.AppendLine();
166+
sb.Append(text);
167+
}
168+
}
169+
return sb.ToString();
170+
}
171+
}

0 commit comments

Comments
 (0)