סופרמרקטים

לפעמים שורות מסוימות בטבלה דורשות כותרת או בלוקים גדולים של טקסט לקחת את רוחב המלא של השולחן. עבור עיצוב תקין של השולחן, המשתמש יכול למזג כמה תאים בטבלה לתוך אחד. Aspose.Words תומך תאים ממוזגים כאשר עובדים עם כל פורמטי קלט, כולל ייבוא תוכן HTML.

איך להגות Table Cells

In In In Aspose.Words, תאים ממוזגים על ידי התכונות הבאות של CellFormat קטגוריה:

    • HorizontalMerge המתאר אם התא הוא חלק ממיזוג אופקי של תאים
    • VerticalMerge המתאר אם התא הוא חלק ממיזוג אנכי של תאים

הערכים של תכונות אלה קובעים את התנהגות המיזוג של תאים:

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));
}
}

מארג' טבלה Cells When Using DocumentBuilder

למזג תאים בטבלה שנוצרה עם DocumentBuilder, אתה צריך להגדיר את סוג המיזוג המתאים עבור כל תא שבו המיזוג צפוי - הראשון CellMerge.First ואז CellMerge.Previous.

כמו כן, עליך לזכור לנקות את הגדרת המיזוג עבור תאים אלה שבהם אין צורך במיזוג - זה יכול להיעשות על ידי הגדרת תא non-merge הראשון. 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 לא משמש, כגון בטבלה קיימת, מיזוג תאים בדרך הקודמת לא יכול להיות קל. במקום זאת, אנו יכולים לעטוף את הפעולות הבסיסיות הכרוכות ביישום תכונות מיזוג לתאים בשיטה שהופכת את המשימה להרבה יותר קלה. שיטה זו דומה לשיטת האוטומציה של Merge, הנקראת למזג מגוון תאים בטבלה.

הקוד להלן ימזג את תאי הטבלה בטווח שצוין, החל מהתא נתון וסיום בתא הסופי. במקרה זה, הטווח יכול לעגל שורות מרובות או עמודות:

// 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");

Vertical and Horizontal Merged Cells in HTML Table

כפי שאמרתי במאמרים קודמים, שולחן ב Microsoft Word היא קבוצה של שורות עצמאיות. לכל שורה יש קבוצה של תאים שאינם תלויים בתאים של שורות אחרות. כך, ב Microsoft Word טבלה אין אובייקט כזה “שטח”, ו"עמודה ראשונה" הוא משהו כמו “מערך התאים הראשונים של כל שורה בטבלה”. זה מאפשר למשתמשים יש שולחן שבו, למשל, השורה הראשונה מורכבת משני תאים - 2 ס"מ ו 1 ס"מ, והשורה השנייה מורכבת משני תאים שונים - 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;
}

עקבו אחרי Horizontally תאים מרורגים

לפעמים לא ניתן לזהות אילו תאים מתמזגים כי כמה גרסאות חדשות יותר של 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();