Sample code for 30+ languages & platforms
Zig Requires Chilkat v11.7.0+

Extract a PDF Table with Merged Cells

See more PDF Text Extraction Examples

Demonstrates how merged cells are reported by the "tables" operation: a header cell that spans several columns has colSpan greater than 1, and a row label that spans several rows has rowSpan greater than 1. Also shows the minRows and minColumns options.

Chilkat Zig Downloads

Zig
const std = @import("std");
const chilkat = @import("chilkat");

pub fn main(init: std.process.Init) !void {
    const alloc = init.arena.allocator();

    // This example requires the Chilkat API to have been previously unlocked.
    // See Global Unlock Sample for sample code.

    // The PDF used in this example is available at spans_table.pdf

    const pdf = try chilkat.Pdf.init();
    defer pdf.deinit();
    pdf.loadFile("qa_data/pdf/spans_table.pdf") catch {
        std.debug.print("{s}\n", .{try pdf.getLastErrorText(alloc)});
        return;
    };

    const json = try chilkat.JsonObject.init();
    defer json.deinit();
    const json_out = try chilkat.JsonObject.init();
    defer json_out.deinit();

    // Grids smaller than minRows x minColumns are not reported as tables.  The defaults are 2 and 2.
    // Setting them higher skips small boxes that are not really tables.
    json.updateInt("minRows", 3) catch {};
    json.updateInt("minColumns", 3) catch {};

    pdf.extractText("tables", json, json_out) catch {
        std.debug.print("{s}\n", .{try pdf.getLastErrorText(alloc)});
        return;
    };

    std.debug.print("Tables found: {d}\n", .{json_out.intOf("count")});
    std.debug.print("{d} rows x {d} columns\n", .{ json_out.intOf("tables[0].rows"), json_out.intOf("tables[0].columns") });

    // A merged cell is reported once, at its top-left position, with its spans.
    // The positions it covers have no cell of their own.
    var row_span: i32 = 0;
    var col_span: i32 = 0;
    var j: i32 = 0;
    const count_j = json_out.sizeOfArray("tables[0].cells");
    while (j < count_j) {
        json_out.setJ(j);
        row_span = json_out.intOf("tables[0].cells[j].rowSpan");
        col_span = json_out.intOf("tables[0].cells[j].colSpan");
        if ((row_span > 1) or (col_span > 1)) {
            std.debug.print("row {d}, col {d}: \"{s}\" spans {d} row(s) and {d} column(s)\n", .{ json_out.intOf("tables[0].cells[j].row"), json_out.intOf("tables[0].cells[j].col"), try json_out.stringOf(alloc, "tables[0].cells[j].text"), row_span, col_span });
        }

        j = j + 1;
    }

    // Sample output:

    // Tables found: 1
    // 6 rows x 6 columns
    // row 0, col 0: "Area" spans 2 row(s) and 1 column(s)
    // row 0, col 1: "City" spans 2 row(s) and 1 column(s)
    // row 0, col 2: "First Half" spans 1 row(s) and 2 column(s)
    // row 0, col 4: "Second Half" spans 1 row(s) and 2 column(s)
    // row 2, col 0: "East" spans 2 row(s) and 1 column(s)
    // row 4, col 0: "West" spans 2 row(s) and 1 column(s)
}