ผสานเซลล์ตาราง

บางครั้งบางแถวในตารางต้องมีหัวข้อหรือบล็อกขนาดใหญ่ของข้อความที่ใช้ความกว้างเต็ม สำหรับการออกแบบที่เหมาะสมของตารางผู้ใช้สามารถผสานเซลล์ตารางหลายเป็นหนึ่ง Aspose.Wordsรองรับการรวมเซลล์เมื่อทำงานกับรูปแบบการป้อนข้อมูลทั้งหมดรวมทั้งการนำเข้าHTMLเนื้อหา.

วิธีการผสานเซลล์ตาราง

ในAspose.Wordsเซลล์ที่ผสานจะถูกแสดงโดยคุณสมบัติต่อไปนี้ของCellFormatคลาส:

  • HorizontalMergeซึ่งอธิบายว่าเซลล์เป็นส่วนหนึ่งของการรวมแนวนอนของเซลล์
  • VerticalMergeซึ่งอธิบายว่าเซลล์เป็นส่วนหนึ่งของการรวมแนวตั้งของเซลล์

ค่าของคุณสมบัติเหล่านี้กำหนดพฤติกรรมผสานของเซลล์:

  • เซลล์แรกในลำดับของเซลล์ที่ผสานจะมีCellMerge.First
  • เซลล์ที่ผสานในภายหลังจะมีCellMerge.Previous
  • เซลล์ที่ไม่รวมจะมีCellMerge.None

work-with-merged-cells-aspose-words-java

การตรวจสอบว่ามีการรวมเซลล์หรือไม่

หากต้องการตรวจสอบว่าเซลล์เป็นส่วนหนึ่งของลำดับของเซลล์ที่ผสาน,เราเพียงแค่ตรวจสอบHorizontalMergeและVerticalMergeคุณสมบัติ.

ตัวอย่างรหัสต่อไปนี้แสดงวิธีการพิมพ์ชนิดผสานเซลล์แนวนอนและแนวตั้ง:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java.git.
Document doc = new Document(getMyDir() + "Table with merged cells.docx");
Table table = (Table) doc.getChild(NodeType.TABLE, 0, true);
for (Row row : (Iterable<Row>) table.getRows())
{
for (Cell cell : (Iterable<Cell>) row.getCells())
{
System.out.println(printCellMergeType(cell));
}
}

ผสานเซลล์ตารางเมื่อใช้DocumentBuilder

เมื่อต้องการผสานเซลล์ในตารางที่สร้างขึ้นด้วยDocumentBuilderคุณต้องตั้งค่าประเภทการผสานที่เหมาะสมสำหรับแต่ละเซลล์ที่คาดว่าการผสาน-ก่อนCellMerge.Firstและจากนั้นCellMerge.Previous.

นอกจากนี้คุณต้องจำไว้ว่าให้ล้างการตั้งค่าผสานสำหรับเซลล์เหล่านั้นที่ไม่จำเป็นต้องผสานซึ่งสามารถทำได้โดยการตั้งค่าเซลล์ที่ไม่รวมเป็นCellMerge.None ล์ทั้งหมดในตารางจะถูกผสาน.

ตัวอย่างรหัสต่อไปนี้แสดงวิธีการสร้างตารางที่มีสองแถวที่เซลล์ในแถวแรกถูกรวมในแนวน:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java.git.
Document doc = new Document();
DocumentBuilder builder = new DocumentBuilder(doc);
builder.insertCell();
builder.getCellFormat().setHorizontalMerge(CellMerge.FIRST);
builder.write("Text in merged cells.");
builder.insertCell();
// This cell is merged to the previous and should be empty.
builder.getCellFormat().setHorizontalMerge(CellMerge.PREVIOUS);
builder.endRow();
builder.insertCell();
builder.getCellFormat().setHorizontalMerge(CellMerge.NONE);
builder.write("Text in one cell.");
builder.insertCell();
builder.write("Text in another cell.");
builder.endRow();
builder.endTable();
doc.save(getArtifactsDir() + "WorkingWithTables.HorizontalMerge.docx");

ตัวอย่างรหัสต่อไปนี้แสดงวิธีการสร้างตารางสองคอลัมน์ที่เซลล์ในคอลัมน์แรกจะรวมในแน:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java.git.
Document doc = new Document();
DocumentBuilder builder = new DocumentBuilder(doc);
builder.insertCell();
builder.getCellFormat().setVerticalMerge(CellMerge.FIRST);
builder.write("Text in merged cells.");
builder.insertCell();
builder.getCellFormat().setVerticalMerge(CellMerge.NONE);
builder.write("Text in one cell");
builder.endRow();
builder.insertCell();
// This cell is vertically merged to the cell above and should be empty.
builder.getCellFormat().setVerticalMerge(CellMerge.PREVIOUS);
builder.insertCell();
builder.getCellFormat().setVerticalMerge(CellMerge.NONE);
builder.write("Text in another cell");
builder.endRow();
builder.endTable();
doc.save(getArtifactsDir() + "WorkingWithTables.VerticalMerge.docx");

ผสานเซลล์ตารางในกรณีอื่นๆ

ในสถานการณ์อื่นๆที่ไม่ได้ใช้DocumentBuilderเช่นในตารางที่มีอยู่การรวมเซลล์ในลักษณะก่อนหน้านี้อาจไม่ง่า แต่เราสามารถห่อการดำเนินงานขั้นพื้นฐานที่เกี่ยวข้องกับการใช้คุณสมบัติผสานกับเซลล์ในวิธีการที่ทำให้งานง่ายขึ้นมาก วิธีการนี้จะคล้ายกับวิธีการผสานอัตโนมัติซึ่งเรียกว่าการผสานช่วงของเซลล์ในตาราง.

รหัสด้านล่างจะรวมเซลล์ตารางในช่วงที่ระบุ,เริ่มต้นที่เซลล์ที่กำหนดและสิ้นสุดที่เซลล์สิ้นสุด. ในกรณีนี้ช่วงสามารถสแปนหลายแถวหรือคอลัมน์:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java.git.
void mergeCells(Cell startCell, Cell endCell)
{
Table parentTable = startCell.getParentRow().getParentTable();
// Find the row and cell indices for the start and end cell.
Point startCellPos = new Point(startCell.getParentRow().indexOf(startCell),
parentTable.indexOf(startCell.getParentRow()));
Point endCellPos = new Point(endCell.getParentRow().indexOf(endCell), parentTable.indexOf(endCell.getParentRow()));
// Create a range of cells to be merged based on these indices.
// Inverse each index if the end cell is before the start cell.
Rectangle mergeRange = new Rectangle(Math.min(startCellPos.x, endCellPos.y),
Math.min(startCellPos.y, endCellPos.y),
Math.abs(endCellPos.x - startCellPos.x) + 1, Math.abs(endCellPos.y - startCellPos.y) + 1);
for (Row row : parentTable.getRows())
{
for (Cell cell : row.getCells())
{
Point currentPos = new Point(row.indexOf(cell), parentTable.indexOf(row));
// Check if the current cell is inside our merge range, then merge it.
if (mergeRange.contains(currentPos))
{
cell.getCellFormat().setHorizontalMerge(currentPos.x == mergeRange.getX() ? CellMerge.FIRST : CellMerge.PREVIOUS);
cell.getCellFormat().setVerticalMerge(currentPos.y == mergeRange.getY() ? CellMerge.FIRST : CellMerge.PREVIOUS);
}
}
}
}

ตัวอย่างรหัสต่อไปนี้แสดงวิธีการผสานช่วงของเซลล์ระหว่างสองเซลล์ที่ระบุ:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java.git.
Document doc = new Document(getMyDir() + "Table with merged cells.docx");
Table table = doc.getFirstSection().getBody().getTables().get(0);
// We want to merge the range of cells found inbetween these two cells.
Cell cellStartRange = table.getRows().get(0).getCells().get(0);
Cell cellEndRange = table.getRows().get(1).getCells().get(1);
// Merge all the cells between the two specified cells into one.
mergeCells(cellStartRange, cellEndRange);
doc.save(getArtifactsDir() + "WorkingWithTables.MergeCellRange.docx");

เซลล์รวมในแนวตั้งและแนวนอนในตารางHTML

ดังที่เราได้กล่าวในบทความก่อนหน้านี้ตารางในMicrosoft Wordคือชุดของแถวที่เป็นอิสระ แต่ละแถวมีชุดของเซลล์ที่เป็นอิสระจากเซลล์ของแถวอื่นๆ ดังนั้นในตารางMicrosoft Wordไม่มีวัตถุเช่น"คอลัมน์"และ"คอลัมน์ที่ 1"เป็นสิ่งที่ชอบ"ชุดของเซลล์ที่ 1 ของแต่ละแถวในตาราง" นี้จะช่วยให้ผู้ใช้มีตารางที่ยกตัวอย่างเช่นแถวที่ 1 ประกอบด้วยสองเซลล์-2 ซม.และ 1 ซม.และแถวที่ 2 ประกอบด้วยสองเซลล์ที่แตกต่างกัน–1 ซม.และกว้าง 2 ซม. และAspose.Wordsสนับสนุนแนวคิดของตารางนี้.

ตารางในHTMLมีโครงสร้างที่แตกต่างกันเป็นหลัก:แต่ละแถวมีหมายเลขเดียวกันของเซลล์และ(มั ดังนั้นถ้าHorizontalMergeและVerticalMergeส่งคืนค่าไม่ถูกต้องให้ใช้ตัวอย่างรหัสต่อไปนี้:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java.git.
Document doc = new Document(getMyDir() + "Table with merged cells.docx");
SpanVisitor visitor = new SpanVisitor(doc);
doc.accept(visitor);
// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java.git.
/// <summary>
/// Helper class that contains collection of rowinfo for each row.
/// </summary>
public static class TableInfo
{
public ArrayList<RowInfo> getRows() { return mRows; }
private ArrayList<RowInfo> mRows = new ArrayList<>();
}
/// <summary>
/// Helper class that contains collection of cellinfo for each cell.
/// </summary>
public static class RowInfo
{
public ArrayList<CellInfo> getCells() { return mCells; };
private ArrayList<CellInfo> mCells = new ArrayList<>();
}
/// <summary>
/// Helper class that contains info about cell. currently here is only colspan and rowspan.
/// </summary>
public static class CellInfo
{
public CellInfo(int colSpan, int rowSpan)
{
mColSpan = colSpan;
mRowSpan = rowSpan;
}
public int getColSpan() { return mColSpan; };
private int mColSpan;
public int getRowSpan() { return mRowSpan; };
private int mRowSpan;
}
public static class SpanVisitor extends DocumentVisitor
{
/// <summary>
/// Creates new SpanVisitor instance.
/// </summary>
/// <param name="doc">
/// Is document which we should parse.
/// </param>
public SpanVisitor(Document doc) throws Exception {
mWordTables = doc.getChildNodes(NodeType.TABLE, true);
// We will parse HTML to determine the rowspan and colspan of each cell.
ByteArrayOutputStream htmlStream = new ByteArrayOutputStream();
HtmlSaveOptions options = new HtmlSaveOptions();
{
options.setImagesFolder(System.getProperty("java.io.tmpdir"));
}
doc.save(htmlStream, options);
// Load HTML into the XML document.
org.jsoup.nodes.Document document = Jsoup.parse(htmlStream.toString());
// Get collection of tables in the HTML document.
Elements tables = document.getElementsByTag("table");
for (Element table : tables) {
TableInfo tableInf = new TableInfo();
// Get collection of rows in the table.
Elements rows = table.getElementsByTag("tr");
for (Element row : rows) {
RowInfo rowInf = new RowInfo();
// Get collection of cells.
Elements cells = row.getElementsByTag("td");
for (Element cell : cells) {
// Determine row span and colspan of the current cell.
String colSpanAttr = cell.attributes().get("colspan");
String rowSpanAttr = cell.attributes().get("rowspan");
int colSpan = StringUtils.isNotBlank(colSpanAttr) ? Integer.parseInt(colSpanAttr) : 0;
int rowSpan = StringUtils.isNotBlank(rowSpanAttr) ? Integer.parseInt(rowSpanAttr) : 0;
CellInfo cellInf = new CellInfo(colSpan, rowSpan);
rowInf.getCells().add(cellInf);
}
tableInf.getRows().add(rowInf);
}
mTables.add(tableInf);
}
}
public int visitCellStart(Cell cell)
{
int tabIdx = mWordTables.indexOf(cell.getParentRow().getParentTable());
int rowIdx = cell.getParentRow().getParentTable().indexOf(cell.getParentRow());
int cellIdx = cell.getParentRow().indexOf(cell);
int colSpan = 0;
int rowSpan = 0;
if (tabIdx < mTables.size() &&
rowIdx < mTables.get(tabIdx).getRows().size() &&
cellIdx < mTables.get(tabIdx).getRows().get(rowIdx).getCells().size())
{
colSpan = mTables.get(tabIdx).getRows().get(rowIdx).getCells().get(cellIdx).getColSpan();
rowSpan = mTables.get(tabIdx).getRows().get(rowIdx).getCells().get(cellIdx).getRowSpan();
}
System.out.println(MessageFormat.format("{0}.{1}.{2} colspan={3}\t rowspan={4}", tabIdx, rowIdx, cellIdx, colSpan, rowSpan));
return VisitorAction.CONTINUE;
}
private ArrayList<TableInfo> mTables = new ArrayList<>();
private NodeCollection mWordTables;
}

แปลงเป็นเซลล์รวมในแนวนอน

บางครั้งไม่สามารถตรวจจับว่าเซลล์ใดถูกผสานเนื่องจากรุ่นใหม่ของMicrosoft Wordบางรุ่นจะไม่ใช้ธงผสานเมื่อเซลล์ถูกผสานเข้าด้วยกันในแนวนอน แต่สำหรับสถานการณ์ที่เซลล์ถูกผสานเข้ากับเซลล์ในแนวนอนตามความกว้างโดยใช้ธงผสานAspose.Wordsจะมีวิธีแปลงเซลล์ConvertToHorizontallyMergedCells วิธีนี้เพียงแค่แปลงตารางและเพิ่มเซลล์ใหม่ตามความจำเป็น.

ตัวอย่างรหัสต่อไปนี้แสดงวิธีการข้างต้นในการดำเนินงาน:

// For complete examples and data files, please go to https://github.com/aspose-words/Aspose.Words-for-Java.git.
Document doc = new Document(getMyDir() + "Table with merged cells.docx");
Table table = doc.getFirstSection().getBody().getTables().get(0);
// Now merged cells have appropriate merge flags.
table.convertToHorizontallyMergedCells();