Files
cc-1c-skills/docs/mxl-dsl-spec.md
T
Nick Shirokov 2a16395951 docs(mxl-compile,mxl-decompile): закрыть дыры каскада, найденные обходом по задачам
Перечитал каскад как модель, идущая от задачи, и нашёл три места, где задача
упиралась в пустоту:

- ключ pictureParameter стоял в схеме DSL, но не был описан нигде, а задача
  «картинка в ячейке» из индекса вела в drawings.md, где её не было. Добавлен
  раздел: picIndex считается с единицы по порядку объявления в pictures,
  выравнивания и положение текста — ключи стиля, pictureParameter — ключ ячейки;
- объектная форма rowStyle с модификатором apply нигде не описана, хотя её
  пишет декомпилятор: модель, разобравшая чужой макет, встречала непонятный
  ключ. Такие формы собраны в mxl-decompile отдельной таблицей — вместе с
  controlType "none", пустым valueType, пустой привязкой к раскладке и записью
  палитры без картинки;
- область печати и повторение шапки при печати DSL не выражает — теперь это
  сказано прямо в print.md, а не выясняется опытным путём.

Индекс задач дополнен колонкой ключей: модель, увидевшая незнакомый ключ
в схеме, сразу находит нужный файл.
2026-08-17 14:23:53 +03:00

44 KiB
Raw Blame History

Спецификация MXL DSL — JSON-формат описания табличного документа

Компактный JSON-формат для описания макетов табличных документов 1С (SpreadsheetDocument). Используется навыками /mxl-compile (JSON → XML) и /mxl-decompile (XML → JSON).

Пример

{
  "columns": 10,
  "defaultWidth": 30,
  "columnWidths": { "1": 15, "2-8": 40, "9-10": 50 },

  "fonts": {
    "default": { "face": "Arial", "size": 10 },
    "bold": { "face": "Arial", "size": 10, "bold": true },
    "header": { "face": "Arial", "size": 14, "bold": true }
  },

  "styles": {
    "default": {},
    "header": { "font": "header", "horizontalAlignment": "Center" },
    "label": { "font": "bold" },
    "bordered": { "border": "Solid" },
    "bordered-right": { "border": "Solid", "horizontalAlignment": "Right" },
    "total-right": { "font": "bold", "topBorder": "Solid", "horizontalAlignment": "Right" }
  },

  "areas": [
    {
      "name": "Заголовок",
      "rows": [
        { "height": 20, "cells": [
          { "col": 1, "span": 10, "style": "header", "param": "ТекстЗаголовка" }
        ]}
      ]
    },
    {
      "name": "ШапкаТаблицы",
      "rows": [
        { "rowStyle": "bordered", "cells": [
          { "col": 1, "text": "№" },
          { "col": 2, "span": 6, "text": "Наименование" },
          { "col": 9, "text": "Кол-во" },
          { "col": 10, "text": "Сумма" }
        ]}
      ]
    },
    {
      "name": "Строка",
      "rows": [
        { "rowStyle": "bordered", "cells": [
          { "col": 1, "param": "НомерСтроки" },
          { "col": 2, "span": 6, "param": "Товар", "detail": "Номенклатура" },
          { "col": 9, "style": "bordered-right", "param": "Количество" },
          { "col": 10, "style": "bordered-right", "param": "Сумма" }
        ]}
      ]
    },
    {
      "name": "Итого",
      "rows": [
        { "cells": [
          { "col": 8, "span": 2, "style": "total-right", "text": "Итого:" },
          { "col": 10, "style": "total-right", "param": "Всего" }
        ]}
      ]
    }
  ]
}

Верхний уровень

Поле Обяз. По умолч. Описание
columns да Количество колонок в раскладке по умолчанию. 0 допустимо: значит, все строки живут в раскладках из columnSets
page нет Формат страницы: "A4-landscape" (780), "A4-portrait" (540) или число. Автоматически вычисляет defaultWidth из суммы пропорций "Nx"
defaultWidth нет 10 Ширина колонок по умолчанию. Игнорируется если задан page и все колонки используют "Nx"
columnWidths нет {} Ширины колонок. Ключи 1-based: "1", "3-14", "5,7,9". Значения: число (абсолют) или "Nx" (множитель от defaultWidth, напр. "2x", "0.5x")
columnStyles нет Оформление колонок: те же ключи, значение — имя стиля (см. «Оформление»)
textLanguages нет ["ru"] Языки, на которых пишется текст, заданный строкой (см. ниже)
fonts нет Именованные шрифты (если не задано, создаётся Arial 10)
styles нет {} Именованные стили (см. «Оформление»)
areas да Массив областей — диапазонов подряд идущих строк (порядок = порядок в документе); имя необязательно
namedAreas нет Именованные области, заданные координатами (см. ниже)
columnSets нет Дополнительные колоночные раскладки (см. «Колоночные раскладки»)
rowGroups нет Группы строк (см. ниже)
columnGroups нет Группы колонок (см. ниже)
header / footer нет Верхний и нижний колонтитулы (см. ниже)
printSettings нет Параметры печати (см. ниже)
pictures нет Палитра картинок: ссылки на библиотеку платформы или данные (см. ниже)
drawings нет Рисунки: картинки, фигуры, надписи (см. ниже)

Области (areas[])

Поле Обяз. Описание
name нет Имя области для Макет.ПолучитьОбласть("Имя")
columnSet нет Ссылка на раскладку из columnSets
rows да Массив строк

Макет собирается из областей — диапазонов подряд идущих строк. Имя делает область именованной: она доступна в коде как Макет.ПолучитьОбласть("Имя") и занимает строки своего диапазона. Область без имени — просто кусок сетки: так описываются строки, не принадлежащие ни одной именованной области.

Именованные области координатами (namedAreas[])

Для областей, которые диапазоном подряд идущих строк не описываются: полоса колонок, прямоугольник, ячейка, а также пересекающиеся с другими.

Поле Обяз. Описание
name да Имя области
rows * Строки: число или диапазон "N-M", 1-based
cols * Колонки: число или диапазон "N-M", 1-based
columnSet нет Колоночная раскладка области. Без ключа выводится из накрытых строк, "" — привязки нет

* Обязательна хотя бы одна из осей.

Тип области не указывается — он следует из того, какие оси заданы, как в ТабличныйДокумент.Область(): только строки → полоса строк, только колонки → полоса колонок, обе оси → прямоугольник, одиночные значения по обеим осям → одна ячейка.

"namedAreas": [
  { "name": "ОбластьПечатиПоВысоте", "rows": "1-48" },
  { "name": "ОбластьПечатиПоШирине", "cols": "1-35" },
  { "name": "HZY", "rows": 9, "cols": "16-17" }
]

Диапазон — та же грамматика, что у columnWidths, но только число или "N-M": список через запятую запрещён, область непрерывна. Имя обязательно, и хотя бы одна ось должна быть задана; нарушение любого из этих правил → ненулевой код выхода и сообщение в stderr.

Строки (rows[])

Поле По умолч. Описание
height Высота строки (если не задана, используется авто)
hidden false Скрыть строку
rowStyle Стиль строки: ложится и на саму строку, и на ВСЕ её колонки (заполняет пустоты рамками)
cells [] Массив ячеек
empty Количество подряд идущих пустых строк (заменяет N отдельных {})

Строка без cells и rowStyle → пустая строка. { "empty": 3 } эквивалентно трём {}.

height и hidden — собственные свойства строки: у ячейки таких нет, и в её оформление они не попадают. Всё остальное оформление строки задаётся через rowStyle.

Короткая форма: список ячеек позиционно

Список ячеек можно записывать позиционно — позиция определяется порядком, col не указывается. Если у строки нет своих свойств, такой список и есть строка; если нужны height, hidden или rowStyle — тот же список кладётся в cells.

Элемент Значение
"текст" Статический текст (text)
{ "ru": "…", "en": "…" } Тот же текст на нескольких языках
"{Имя}" Параметр (param)
">" Продолжение ячейки слева — увеличивает её span
`" "`
null Пустая колонка: позиция занята, ячейка не создаётся
{ ... } Обычная ячейка без col; нужна для style, detail, template

Объект-элемент трактуется по его ключам: если среди них есть ключ ячейки (span, rowspan, style, param, detail, text, template, valueType, controlType, value, control) — объект описывает свойства ячейки. Иначе он целиком считается её текстом, а его ключи — идентификаторами языков.

"rows": [
  ["Вид", "Остаток", ">", "Итог"],
  ["|",   "начало",  "конец", "|"],
  ["{Вид}", "{Нач}", "{Кон}", "{Итог}"]
]

Здесь «Вид» и «Итог» объединены по вертикали на две строки, «Остаток» — по горизонтали на две колонки.

{ "rowStyle": "итог", "cells": [null, null, null, "Итого:", "{Всего}"] }

Ограничение у формы одно: ею не выразить текст, совпадающий с ">", "|" или с шаблоном "{...}" — такие ячейки записываются объектом с ключом text.

Маркеру нужно, что продолжать: ">" требует ячейку слева в той же строке, "|" — ячейку сверху. Объектный элемент не должен нести col: позиция уже задана порядком. Число элементов не может превышать columns. Нарушение любого из этих правил → ненулевой код выхода и сообщение в stderr.

Ячейки (cells[])

Поле Обяз. По умолч. Описание
col да Позиция колонки (1-based). В короткой форме строки не указывается — позиция берётся из порядка
span нет 1 Объединение по горизонтали (количество колонок)
rowspan нет 1 Объединение по вертикали (количество строк)
style нет rowStyle Стиль ячейки (переопределяет rowStyle)
param нет Параметр заполнения
detail нет Параметр расшифровки. Самостоятельный ключ: ставится и на ячейку без param — с текстом, пустую или поле ввода
text нет Статический текст. Строка или объект { ru, en } — см. ниже
template нет Шаблонный текст с [Параметр]. Строка или объект, как text
valueType нет Тип значения: ячейка становится полем ввода (см. ниже)
controlType нет input Элемент управления поля ввода: input или checkbox. Только вместе с valueType
value нет Значение в поле ввода. Только вместе с valueType
control нет Настройки элемента управления в записи платформы (base64). Раундтрип, не для ручного авторинга
note нет Примечание к ячейке (см. ниже)

Содержимое ячейки

Задаётся ровно одним из ключей, объявлять способ заполнения отдельно не нужно:

  • param — параметр заполнения;
  • template — текст со вставками [Параметр];
  • text — статический текст;
  • ничего — пустая ячейка (нужна, например, ради рамки).

Текст на нескольких языках

text и template принимают строку или объект «язык → текст». Объект даёт по надписи на каждый язык, в порядке ключей. Строка означает один и тот же текст на всех языках макета — по умолчанию только русский.

{ "col": 1, "text": "Наименование" }
{ "col": 2, "text": { "ru": "Поставщик", "en": "Supplier" } }

Набор языков задаётся документным ключом textLanguages:

{ "columns": 3, "textLanguages": ["ru", "en"], "areas": [] }

С таким объявлением "Наименование" из примера выше даст надпись и под ru, и под en.

Ключ ни на что в конфигурации не смотрит — это просто список языков, на которые разворачивается строка.

Пустая строка — это текст: ячейка с "text": "" даёт пустую надпись, а не ячейку без текста.

Ячейка-поле ввода

Ячейка может не показывать текст, а принимать значение от пользователя — так делают макеты для ввода данных. Достаточно задать тип значения:

{ "col": 1, "valueType": "Number(15,3,nonneg)" }
{ "col": 2, "valueType": "String(10)" }
{ "col": 3, "valueType": "Boolean", "controlType": "checkbox" }
{ "col": 4, "valueType": "CatalogRef.Валюты" }
{ "col": 5, "valueType": "Boolean + String + Date + CatalogRef.Валюты" }
{ "col": 6, "valueType": "AnyRef" }

Грамматика типа:

Запись Значение
Boolean булево
String, String(10), String(10,fixed) строка; без длины — неограниченная, fixed — фиксированной длины
Number, Number(15,3), Number(15,3,nonneg) число; без параметров — без ограничения разрядности, nonneg — неотрицательное
Date, DateTime, Time дата, дата со временем, время
CatalogRef.Валюты, DocumentRef.Реализация, EnumRef.Статусы, DefinedType.Сумма ссылочный тип
CatalogRef, DocumentRef, AnyRef категория целиком: любая ссылка этого вида
A + B составной тип; повтор одного примитива недопустим

Русские имена принимаются наравне с английскими: Число(15,3), Строка(10), СправочникСсылка.Валюты.

text и template в такой ячейке недопустимы — платформа не показывает текст там, где вводится значение. param и detail допустимы: они описывают заполнение и расшифровку, а не содержимое.

Пустой тип "valueType": "" — «ячейка содержит значение», но тип не ограничен.

Значение поля ввода задаётся ключом value, и его тип выражается литералом JSON: строка — строкой, число — числом, булево — true/false. Приведения к объявленному типу не происходит: платформа хранит значение с его собственным типом и совпадать с объявленным он не обязан (у ссылочного и составного типа значение всегда строковое). Пустая строка означает пустое значение объявленного типа. Дата записывается строкой в формате ГГГГ-ММ-ДДTчч:мм:сс и читается как дата только у ячейки, объявленной датой.

{ "col": 1, "valueType": "Number(15,3)", "value": 12.5 }
{ "col": 2, "valueType": "String(10)", "value": "5" }
{ "col": 3, "valueType": "Boolean", "value": true }
{ "col": 4, "valueType": "DateTime", "value": "" }

controlType нужен редко: умолчание платформы — поле ввода, и оно применяется ко всем типам, включая Boolean. Флажок задаётся явно. Значение "none" (тега элемента управления нет вовсе) — форма раундтрипа, для ручного авторинга не нужна.

Примечание к ячейке

Всплывающая подсказка, которую платформа показывает при наведении. Задаётся ключом note — строкой, объектом «язык → текст» или полной формой:

{ "col": 1, "text": "Итого", "note": "Сумма без НДС" }
{ "col": 2, "note": { "ru": "на дату документа", "en": "as of the document date" } }
{ "col": 3, "note": { "text": "не более 20%", "style": "жёлтая-подсказка" } }
{ "col": 4, "note": { "text": "…", "autoSize": false,
                      "box": { "top": 58, "left": -175, "bottom": 362, "right": 478 } } }

Объект трактуется по ключам — так же, как текст ячейки в короткой форме строки: есть ключ примечания (text, style, box, autoSize, anchor) → это описание примечания, иначе ключи считаются идентификаторами языков.

Поле По умолч. Описание
text Текст подсказки: строка или объект «язык → текст»
style стиль подсказки Имя стиля из styles; без него — оформление, которое даёт Конфигуратор
autoSize true Подгонять ли размер окошка под текст
box канонический Смещения окошка: top, left — положение, bottom, right — размер
anchor { row: 1, col: 1 } Якорь начала окошка. Раундтрип, не для ручного авторинга

Координаты ячейки в примечании не задаются — платформа привязывает конец окошка к самой ячейке, и компилятор проставляет это сам. autoSize и box независимы: при автоподгоне размера положение окошка всё равно хранится.

Колонтитулы

У верхнего и нижнего колонтитула по три слота — left, center, right — и общие настройки:

"header": {
  "font": "мелкий",
  "verticalAlignment": "Bottom",
  "startPage": 2,
  "left": "Слева\nвторая строка",
  "center": "Стр. [&НомерСтраницы] из [&СтраницВсего]",
  "right": { "ru": "Справа", "en": "Right" }
},
"footer": {
  "show": false,
  "center": { "formatted": "<b>Итог</> <colorstyle -16>красным</>" }
}
Поле По умолч. Описание
left, center, right Текст слота: строка, объект «язык → текст» или { "formatted": … }
font Имя шрифта из fonts — на весь колонтитул
verticalAlignment Положение текста по вертикали: Top, Center, Bottom
show true Выводить ли колонтитул
startPage 1 Страница, с которой колонтитул печатается

Текст может быть многострочным (\n) и содержать поля [&НомерСтраницы], [&СтраницВсего], [&Дата], [&Время] — платформа подставляет их при печати. { "formatted": … } — форматированная строка: разметка живёт прямо в тексте (<b>жирный</>, <fontsize 12>, <colorstyle -16>).

Параметры печати

Плоский объект; имя ключа совпадает с именем свойства в выгрузке:

"printSettings": {
  "pageOrientation": "Landscape",
  "topMargin": 500, "leftMargin": 500, "bottomMargin": 500, "rightMargin": 500,
  "headerSize": 1000, "footerSize": 1000,
  "fitToPage": true, "firstPageNumber": 7
}

Допустимые ключи: pageOrientation, scale, collate, copies, perPage, topMargin, leftMargin, bottomMargin, rightMargin, headerSize, footerSize, fitToPage, blackAndWhite, printerName, paper, paperSource, pageWidth, pageHeight, duplexType, pagePlacementAlternation, firstPageNumber. Незнакомый ключ — ошибка. Порядок в объекте не важен: компилятор пишет свойства в том порядке, что и платформа.

Группы строк и колонок

Диапазон строк или колонок, который сворачивается кнопкой на полях. Задаются плоским списком; вложенность выражена вхождением одного диапазона в другой:

"rowGroups": [
  { "rows": "2-4" },
  { "rows": 3 },
  { "rows": 5, "name": "Итоговая", "collapsed": true, "titleLocation": "begin" }
],
"columnGroups": [
  { "cols": "2-3", "name": { "ru": "Показатели", "en": "Values" } },
  { "cols": 3 }
]
Поле Обяз. По умолч. Описание
rows / cols да Диапазон 1-based: число или "N-M"
name нет Имя группы: строка или объект «язык → текст»
collapsed нет false Свёрнута ли группа при открытии
titleLocation нет auto Расположение заголовка: begin, end, auto

Диапазоны либо вложены, либо не пересекаются — частичное пересечение платформа не хранит, и компилятор отвергает его с ненулевым кодом выхода. Число уровней вложенности считается само. Порядок в списке не важен: компилятор пишет группы так же, как платформа, — родитель раньше вложенных, по возрастанию начала.

Рисунки и картинки

Рисунок — объект поверх сетки ячеек: картинка, фигура или надпись. Его положение задают два якоря: ячейка плюс смещение в точках от её левого верхнего угла.

"pictures": {
  "знак":  { "ref": "v8ui:Стоп48" },
  "логотип": { "data": "iVBORw0KGgo...", "transparent": { "x": 24, "y": 29 } }
},
"drawings": [
  { "type": "Picture", "picture": "логотип", "name": "Логотип",
    "begin": { "row": 1, "col": 1 },
    "end":   { "row": 3, "col": 2, "dy": 34, "dx": 115 },
    "pictureSize": "Proportionally", "detail": "ПараметрРасшифровки" },
  { "type": "Rectangle", "style": "заливка",
    "line": { "style": "Dashed", "width": 2 },
    "sides": { "left": true, "top": true, "right": false, "bottom": false },
    "begin": { "row": 5, "col": 1 }, "end": { "row": 6, "col": 3 } },
  { "type": "Text", "text": { "ru": "Подпись", "en": "Signature" },
    "begin": { "row": 8, "col": 1 }, "end": { "row": 8, "col": 3, "dy": 12 } }
]
Поле Обяз. По умолч. Описание
type нет Picture Picture, Rectangle, Ellipse, Line, Text, Chart, GanttChart
begin / end да Якоря: row, col (1-based) и смещения dy, dx в точках
picture нет Имя записи из pictures
pictureSize нет Stretch Как картинка заполняет прямоугольник: Stretch, AutoSize, Proportionally, RealSize
text нет Надпись: строка или объект «язык → текст»
name нет Имя рисунка, по которому к нему обращаются из кода
detail нет Параметр расшифровки
style нет Именованный стиль: заливка, шрифт, выравнивание надписи
line нет Линия рисунка (она же его рамка) — как border у ячейки
sides нет Какие стороны рамки видны: left, top, right, bottom
id нет номер по порядку Идентификатор рисунка
zOrder нет номер по порядку Порядок перекрытия: чем больше, тем выше

Порядок в списке drawings — порядок в документе; кто кого перекрывает, задаёт zOrder.

Запись в pictures — либо ссылка (ref), либо сами данные в base64 (data). Ссылкой задаются и предопределённая картинка платформы, и общая картинка конфигурации — пишутся они одинаково, префиксом v8ui:. Пустая запись {} — картинка не задана, такое в макетах встречается. Прозрачность задаётся ключом transparent в одной из двух форм: false — прозрачного фона нет; { "x": …, "y": … } — прозрачным считается цвет пикселя с этими координатами внутри картинки (по флажку «прозрачный фон» Конфигуратор берёт её правый нижний пиксель).

Одну запись pictures могут использовать несколько рисунков — данные в макете не дублируются.

Картинка в ячейке

Картинка бывает не только поверх сетки, но и внутри ячейки — тогда её задаёт стиль, а сама картинка берётся из той же палитры pictures:

{
  "columns": 2,
  "pictures": { "стоп": { "ref": "v8ui:Стоп48" } },
  "styles": { "значок": { "picIndex": 1, "picHorizontalAlignment": "Center",
                          "picVerticalAlignment": "Center", "textPosition": "Bottom" } },
  "areas": [{ "rows": [
    [{ "style": "значок", "text": "удалить", "pictureParameter": "Удалить" }]
  ]}]
}
  • picIndex — номер записи в pictures, считая с единицы в порядке объявления;
  • picHorizontalAlignment, picVerticalAlignment, pictureSizeMode, textPosition — как картинка стоит в ячейке и где относительно неё текст (значения — в разделе «Полный список свойств стиля»);
  • pictureParameter — ключ самой ЯЧЕЙКИ, а не стиля: имя параметра, которым картинку подставляют из кода, как param подставляет текст. С текстом ячейки уживается.

rowStyle — оформление строки

Стиль применяется ко ВСЕЙ ширине строки: позиции без явных ячеек получают тот же стиль. Так в табличных строках получаются сплошные рамки. Он же становится оформлением самой строки — именно так платформа хранит строку, оформленную целиком.

Стиль конкретной ячейки (style) перекрывает rowStyle для этой ячейки.

Если в предыдущих строках той же области есть ячейки с rowspan, их колонки при автозаполнении пропускаются.

Оформление: шрифты, стили, цвета, рамки

Оформление в табличном документе — одна сущность на всех: ячейка, строка и колонка ссылаются на один и тот же именованный стиль. Ячейка — ключом style, строка — rowStyle, колонка — через columnStyles.

Шрифты (fonts.<name>)

Поле По умолч. Описание
face "Arial" Имя шрифта
size 10 Размер (бывает дробным: 8.3)
bold false Жирный
italic false Курсив
underline false Подчёркнутый
strikeout false Зачёркнутый

Шрифт "default" используется, когда стиль не указывает шрифт явно. Если не определён, создаётся автоматически (Arial 10).

Вместо собственного описания шрифт может быть ссылкой — на элемент стиля конфигурации или на системный шрифт. Тогда у него единственное поле:

"fonts": {
  "основной":  { "ref": "style:TextFont" },
  "системный": { "ref": "sys:DefaultGUIFont" }
}

Это та же запись, что у шрифта в описании формы.

Стили (styles.<name>)

Ключ стиля — имя свойства так, как оно называется в выгрузке. Ниже частые; полный перечень — в разделе «Полный список свойств стиля».

Поле Описание
font Ссылка на имя из fonts
horizontalAlignment Left, Center, Right, Justify, Auto
verticalAlignment Top, Center, Bottom
textPlacement Что делать с длинным текстом: Wrap (перенос), Cut (обрезать), Block, Auto
backColor Цвет фона (см. «Цвет»)
textColor Цвет текста
border, leftBorder, topBorder, rightBorder, bottomBorder Рамка (см. «Рамка»)
borderColor Цвет рамки
format Формат данных 1С: "ЧЦ=15; ЧДЦ=2", "ДФ=dd.MM.yyyy"
hidden Скрыть
protection Защита от редактирования
indent Отступ
textOrientation Поворот текста, в десятых долях градуса (900 = 90°)

Значения перечислений регистр не различают: "center" и "Center" равнозначны.

"styles": {
  "шапка": {
    "font": "жирный",
    "horizontalAlignment": "Center",
    "verticalAlignment": "Center",
    "textPlacement": "Wrap",
    "backColor": "#EBEBEB"
  },
  "итог": { "font": "жирный", "topBorder": "Solid", "horizontalAlignment": "Right" }
}

Цвет

Строка в одной из четырёх форм — это нотация самой платформы:

Форма Значение
#RRGGBB RGB-hex, напр. #FFFFC0
style:ИмяСтиля Элемент стиля конфигурации или платформы, напр. style:FormBackColor
web:Имя Цвет из web-палитры, напр. web:Gainsboro, web:FireBrick
win:Имя Системный цвет Windows, напр. win:ButtonText

Имя должно существовать в своей палитре — несуществующее платформа отвергнет при загрузке.

Рамка

Пять ключей: border — все четыре стороны сразу, leftBorder / topBorder / rightBorder / bottomBorder — по отдельности. Значение одинаковое у всех:

Запись Значение
"Solid" Стиль линии, ширина 1
{ "style": "Solid", "width": 2 } Стиль и ширина

Стили линии: None, Solid, Dotted, Dashed, DashDotted, DashDottedDotted, ThinDashed, LargeDashed, ThickDashed, Double. Конфигуратор предлагает разные наборы в разных местах — у рамки ячейки одни, у линии рисунка другие, — но палитра одна на документ.

Задавать стороны по отдельности можно всегда: если все четыре совпали, компилятор сам свернёт их в один border — так это хранит платформа.

"рамка-снизу":  { "bottomBorder": "Dotted" },
"рамка-вокруг": { "border": { "style": "Solid", "width": 2 } }

Стиль колонки (columnStyles)

Колонка несёт то же оформление, что ячейка и строка. Ключи — та же грамматика диапазонов, что у columnWidths; значение — имя стиля.

"columnWidths": { "1": 30, "2-3": 15 },
"columnStyles": { "1": "по-центру", "4": "скрытая" }

Внутри columnSets работает тот же ключ. Ширина и стиль независимы: колонка может иметь только ширину, только стиль или и то, и другое.

Колоночные раскладки (columnSets)

Группа строк может иметь собственные ширины колонок — в 1С это «индивидуальная ширина колонок». Документные columns и columnWidths описывают раскладку по умолчанию; дополнительные объявляются в columnSets, а область ссылается на нужную ключом columnSet — так же, как ячейка ссылается на styles через style.

{
  "columns": 52,
  "columnWidths": { "1": 8 },
  "columnSets": {
    "таблица": { "columns": 52, "columnWidths": { "1": 7, "2-52": 24 } }
  },
  "areas": [
    { "name": "Шапка", "rows": [["Отчёт о продажах"]] },
    { "name": "ТабличнаяЧасть", "columnSet": "таблица",
      "rows": [["№", "Номенклатура"]] }
  ]
}

Раскладка описывается той же парой полей, что и документная: columns — количество колонок (у раскладок оно обычно разное), columnWidths — ширины. Ключ словаря — имя раскладки; в макетах, полученных декомпиляцией, это идентификатор из исходного файла, при описании с нуля — любая строка.

Все строки области получают раскладку области, поэтому одна область не может смешивать раскладки. Позиции колонок (col, span) проверяются по ширине раскладки СВОЕЙ области, а не документной.

Ссылка на необъявленную раскладку → ненулевой код выхода и сообщение в stderr.

Полный список свойств стиля

Имя ключа совпадает с именем свойства в выгрузке — исключений нет. Частые свойства с примерами — в разделе «Оформление», здесь полный перечень.

Тип значения:

  • число — целое;
  • да/нетtrue / false;
  • перечисление — одно из указанных, регистр не важен;
  • цвет#RRGGBB, style:Имя, web:Имя, win:Имя;
  • линия"Solid" либо { style, width };
  • текст — строка (разворачивается на языки макета).

Текст и выравнивание

Ключ Тип Значение
font имя Ссылка на имя из fonts
horizontalAlignment перечисление Left, Center, Right, Justify, Auto
verticalAlignment перечисление Top, Center, Bottom
textPlacement перечисление Wrap, Cut, Block, Auto
textOrientation число Поворот в десятых долях градуса: 900 = 90°
textColor цвет Цвет текста
indent число Отступ текста
autoIndent число Автоматический отступ
format текст Формат данных: "ЧЦ=15; ЧДЦ=2"
editFormat текст Формат редактирования
mask текст Маска ввода
markNegatives да/нет Выделять отрицательные

Фон и рамка

Ключ Тип Значение
backColor цвет Цвет фона
pattern перечисление WithoutPattern, Solid, Pattern1Pattern17 (в Конфигураторе «Узор 1» … «Узор 17»)
patternColor цвет Цвет узора
border линия Все четыре стороны
leftBorder, topBorder, rightBorder, bottomBorder линия Отдельная сторона
borderColor цвет Цвет рамки

Поведение

Ключ Тип Значение
hidden да/нет Скрыть
protection да/нет Защита от редактирования
print да/нет Выводить на печать
hyperLink да/нет Гиперссылка
detailsUse перечисление Использование расшифровки: Cell, Row, WithoutProcessing
autoMarkIncomplete да/нет Автоотметка незаполненного
bySelectedColumns да/нет По выделенным колонкам
columnSizeChange перечисление Normal, QuickChange
autoWidthCalculation да/нет Автоматический расчёт ширины
widthWeightFactor число Весовой коэффициент ширины

Картинка в ячейке

Ключ Тип Значение
picIndex число Номер картинки
pictureSizeMode перечисление AutoSize, Proportionally, RealSize
picHorizontalAlignment перечисление Auto, Center, Left, Right
picVerticalAlignment перечисление Top, Center, Bottom
textPosition перечисление Положение текста относительно картинки: Auto, Top, Right, Bottom

Чего в стиле нет

  • width — свойство колонки, задаётся через columnWidths;
  • height — свойство строки, задаётся ключом height у строки;
  • fillType — выводится из того, каким ключом задано содержимое ячейки (text / param / template);
  • containsValue, valueType, controlType — свойства конкретной ячейки, а не общего оформления: задаются ключами ячейки valueType и controlType;
  • линия рисунка и её стороны — свойства рисунка: задаются его ключами line и sides (у ячейки такого свойства нет вовсе).

Ограничения

DSL описывает не все конструкции табличного документа. Перечисленное ниже теряется при round-trip (/mxl-decompile/mxl-compile): в JSON оно не попадает, в сгенерированный XML не возвращается.

  • объединения, не привязанные к ячейке (по всей высоте или ширине документа);
  • настройки диаграмм (Chart, GanttChart) — сам рисунок сохраняется, его содержимое нет;
  • область печати.

Пересборка макета из DSL — это полная перегенерация, а не точечная правка XML, поэтому diff после round-trip обычно шире фактической доработки.

Отдельно про побайтовое совпадение. В макетах, которые долго правили в Конфигураторе, встречаются следы прежних состояний: формат ячейки может нести ширину колонки, которая с тех пор изменилась. Такие значения не описывают итоговый документ и из него не выводятся, поэтому собранный XML совпадёт с исходным не всегда — при полностью сохранённом содержании.