Skip to content

Instantly share code, notes, and snippets.

@jakob-stoeck
Created January 15, 2025 03:25
Show Gist options
  • Save jakob-stoeck/2d1e2e774ab20ad8f4ff84c585f63814 to your computer and use it in GitHub Desktop.
Save jakob-stoeck/2d1e2e774ab20ad8f4ff84c585f63814 to your computer and use it in GitHub Desktop.
Create LaTeX booktabs-like tables in Google Docs
// Create a table with less bloat in Google Docs
// No vertical lines, and no horizontal lines except for header and footer
// Inspired by https://ctan.org/pkg/booktabs
function createBooktabsTable() {
// Table configuration
const numRows = 5; // Adjust as needed
const numCols = 4; // Adjust as needed
const doc = DocumentApp.getActiveDocument();
createBooktabsTableInternal(numRows, numCols, doc)
}
// Apply Booktabs-style formatting
function createBooktabsTableInternal(numRows, numCols, doc) {
const body = doc.getBody();
// Insert a table
const table = body.appendTable();
// Populate the table with rows and cells
for (let i = 0; i < numRows; i++) {
const row = table.appendTableRow();
for (let j = 0; j < numCols; j++) {
const content = i === 0 ? `Header ${j + 1}` : `Row ${i}, Col ${j + 1}`
const cell = row.appendTableCell(content);
// Style header row
// TODO this can be an updateTableStyle with tableRange https://googleapis.dev/nodejs/googleapis/latest/docs/interfaces/Schema$UpdateTableCellStyleRequest.html#tableStartLocation
// but I haven’t checked how to set TextStyle inside a table cell, yet
cell.getChild(0).asText().setBold(i === 0 ? true : false);
}
}
doc.saveAndClose();
// Google Apps Script alone has no means to change cell properties like borders.
// That’s why we use Docs service. If you use this inside an Apps Script ensure to under: "Services +" add "Docs"
const docId = doc.getId();
const i = body.getChildIndex(table);
const index = Docs.Documents.get(docId).body.content[i + 1].startIndex;
const noBorder = { dashStyle: "SOLID", width: { magnitude: 0, unit: "PT" }, color: { color: {} } };
const thinBorder = { dashStyle: "SOLID", width: { magnitude: 1, unit: "PT" }, color: { color: {} } };
const thickBorder = { dashStyle: "SOLID", width: { magnitude: 1.5, unit: "PT" }, color: { color: {} } };
const noBorders = {
updateTableCellStyle: {
tableCellStyle: {
borderRight: noBorder,
borderLeft: noBorder,
borderTop: noBorder,
borderBottom: noBorder,
},
tableStartLocation: { index },
fields: "borderRight,borderLeft,borderTop,borderBottom",
}
}
const tableHeader = {
updateTableCellStyle: {
tableCellStyle: {
borderTop: thickBorder,
borderBottom: thinBorder,
},
tableRange: {
tableCellLocation: {
columnIndex: 0,
rowIndex: 0,
tableStartLocation: { index }
},
columnSpan: numCols, // optional ?
rowSpan: 1, // optional ?
},
fields: "borderTop,borderBottom",
}
}
const tableFooter = {
updateTableCellStyle: {
tableCellStyle: {
borderBottom: thickBorder
},
tableRange: {
tableCellLocation: {
columnIndex: 0,
rowIndex: numRows-1,
tableStartLocation: { index }
},
columnSpan: numCols, // optional ?
rowSpan: 1, // optional ?
},
fields: "borderBottom",
}
}
const requests = [noBorders, tableHeader, tableFooter];
const resp = Docs.Documents.batchUpdate({ requests }, docId);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment