Как получить ширину стола

Я хочу получить ширину таблицы в Документах Google. На следующем снимке экрана показан демонстрационный документ. У него есть только таблица, имеющая одну строку и только одну ячейку. Таблица была добавлена ​​путем нажатия кнопки «Вставить» ›Таблица, а затем опции вставки таблицы с одной строкой и одной ячейкой. После вставки таблица не обрабатывалась.

В таблице классов из таблицы классов скриптов Google Apps нет метода для получения ширины, также как и в строке класса, но в ячейке класса есть getWidth(), поэтому я попытался использовать его, но он возвращает null. Я владелец документа, он хранится в My Unit, я использую старую среду выполнения (Mozilla Rhino), Chrome, учетную запись G Suite. Проект был создан из пользовательского интерфейса Документов, нажав Инструменты ›Редактор скриптов.

Вот код (больше в проект ничего не включено)

function myFunction() {
  const doc = DocumentApp.getActiveDocument();
  const body = doc.getBody();
  const tables = body.getTables();
  const table = tables[0];
  const row = table.getRow(0);
  const cell = row.getCell(0);
  const width = cell.getWidth();
  Logger.log(width);
}

Код запускался из редактора скриптов. Вот журнал

Я уже искал в системе отслеживания проблем getWidth. Некоторые результаты были возвращены, но ни один из них не выглядит связанным.

Я уже искал ТАК.

Скрипт Google Apps getWidth () для ширины ячейки таблицы документа возвращает значение null Хотя это может выглядеть как дубликат, речь идет о вставке изображения . С другой стороны, ОП попытался

var width = insertPlace.getParent().asParagraph().asTableCell().getWidth();

но это тоже не сработало. Текущий ответ касается получения ширины изображения, вставленного с Google Диска.

Итак, вопрос: Как получить ширину таблицы?

Если getWidth() содержит ошибки, есть ли другой способ найти ширину таблицы не только тогда, когда таблица использует ширину по умолчанию, но и когда она меньше?


person Rubén    schedule 14.08.2020    source источник


Ответы (3)


Это записанный

ja ... @ google.com

Статус: не исправить (предполагаемое поведение)

Здравствуйте, спасибо за ваш отчет. Функция getWidth возвращает null, если ширина ячейки не изменилась. Вы можете вручную изменить ширину или использовать метод setWidth, чтобы адаптировать его к размеру изображения. Дополнительная информация: https://developers.google.com/apps-script/reference/document/table-cell#setWidth(Number)

du ... @ google.com

Статус: не исправить (предполагаемое поведение)

Hi,

Несмотря на то, что все это не задокументировано, предполагаемое поведение новой таблицы состоит в том, чтобы получить значение null для атрибутов, которые не установлены. Если вы выберете ячейку и измените ее форматирование (размер шрифта, курсив и т. Д.), Вы получите значения для этих атрибутов.

Что касается ширины ячейки, то при создании новой таблицы все ячейки представляют собой «равномерно распределенные ячейки», то есть у нее нет «фиксированной ширины». Если вы измените ширину ячейки, она изменится на фиксированную ширину. Если вы измените ширину по умолчанию для всей таблицы, все ячейки изменятся на фиксированную ширину. Предполагаемое поведение Google Doc API - возвращать ширину только для ячеек с фиксированной шириной.

Я реализовал следующий обходной путь, который будет регистрировать ширину каждой ячейки и общую ширину таблицы (ширина по умолчанию для новой таблицы составляет 450 точек).

Обходной путь:

/**
 * Code written by [email protected]
 * @see https://issuetracker.google.com/issues/143810853#comment2
 */
function getTabeCellAttributes() {
  var fileId = '[FILE-ID]';
  var textInTableCell = "test";
  var body = DocumentApp.openById(fileId).getBody();  

  var tableRow = body.findText(textInTableCell).getElement().getParent().getParent().getParent().asTableRow();
  var evenlyDistributedCells = 0;
  var defaultTableWidth = 450;
  var totalWidth = 0;
 
  for(var i=0; i<tableRow.getNumChildren(); i++) {
    var tableCell = tableRow.getChild(i).asTableCell();
    var tableCellWidth = tableCell.getWidth();
   
    if(tableCellWidth == null) {
      evenlyDistributedCells++;
    }
    else {
      totalWidth += tableCellWidth;
      defaultTableWidth -= tableCellWidth;
      Logger.log("Width of cell number: " + (i+1) + " is: " + tableCellWidth)
    }
  }
 
  if (evenlyDistributedCells!=0) {
    var evenlyDistributedWidth = defaultTableWidth/evenlyDistributedCells;
    totalWidth += defaultTableWidth;
    Logger.log('There are ' + evenlyDistributedCells + ' evenly distributed cells with a width of: ' + evenlyDistributedWidth)
  }
  else {
    Logger.log("There are no evenly distributed cells, all cells have a fixed width.")
  }
 
  Logger.log('The total width of the table is: ' + totalWidth);
}
  • Код не принадлежит мне и не написан мной, это всего лишь цитата из Issueetracker.
person TheMaster    schedule 14.08.2020
comment
Итак, в случае таблицы, которая использует ширину по умолчанию, единственный способ - вычислить ширину тела (ширина страницы - левое поле - правое поле), верно? - person Rubén; 15.08.2020
comment
@ Rubén Может быть, но разве это не зависит от таблицы, которую вы создаете? Если вы создадите таблицу 1x3, вам, возможно, придется разделить ее. - person TheMaster; 15.08.2020
comment
Я ищу ширину таблицы. Я использовал getWidth ячейки таблицы классов, потому что таблица классов не имеет этого метода. Если Table Cell getWidth возвращает null, это не помогает в случае, упомянутом в вопросе. - person Rubén; 15.08.2020
comment
@ Rubén В связанном вопросе есть отличная ссылка с кодом Issueetracker.google.com/issues/143810853#comment2 - person TheMaster; 15.08.2020

Спасибо @TheMaster за упоминание о проблемах (мне не удалось их найти). Ниже приведен очень простой способ получить размер таблицы, который подходит для конкретного случая, когда таблица является дочерним элементом тела документа.

function myFunction1() {
  const doc = DocumentApp.getActiveDocument();
  const body = doc.getBody();
  const attributes = body.getAttributes();
  const width = attributes[DocumentApp.Attribute.PAGE_WIDTH] - attributes[DocumentApp.Attribute.MARGIN_LEFT] - attributes[DocumentApp.Attribute.MARGIN_RIGHT];
  Logger.log(width);
}

Размер страницы по умолчанию для меня - Letter (ширина = 8,5 дюйма), а поля - 1 дюйм.

Ширина зарегистрированной таблицы составила 468 точек (1 дюйм = 72 точки) = 6,5 дюймов, поэтому ширина была ожидаемой.

person Rubén    schedule 15.08.2020

Я считаю вашей целью следующее.

  • Вы хотите получить ширину таблицы из таблицы, созданной в качестве размера по умолчанию с помощью скрипта Google Apps.

Проблема и решение:

К сожалению, на текущем этапе нет методов для получения ширины таблицы из таблицы, созданной в качестве размера по умолчанию в сервисе Google Document и Docs API. Об этом уже упоминалось в https://stackoverflow.com/a/63420215 и https://stackoverflow.com/a/63421935. Итак, в этом ответе я хотел бы предложить обходной путь для получения ширины таблицы с помощью скрипта Google Apps.

В этом обходном пути я использую Microsoft Word. Последовательность этого обходного пути выглядит следующим образом. В этом потоке предполагается, что был создан документ Google, подобный вашему вопросу.

  1. Преобразуйте документ Google (данные DOCX) в Microsoft Word с помощью Drive API.
  2. Parse DOCX data using Google Apps Script.
    • When the converted DOCX data is unzipped, the data can be analyzed as the XML data. Fortunately, at Microsoft Docs, the detail specification is published as Open XML. So in this case, Microsoft Docs like XLSX, DOCX and PPTX can be analyzed using XmlService of Google Apps Script. I think that this method will be also useful for other situations.
  3. Получите ширину таблицы из данных DOCX.

Пример сценария:

function myFunction() {
  const documentId = DocumentApp.getActiveDocument().getId();
  const url = "https://docs.google.com/feeds/download/documents/export/Export?exportFormat=docx&id=" + documentId;
  const blob = UrlFetchApp.fetch(url, {headers: {authorization: `Bearer ${ScriptApp.getOAuthToken()}`}}).getBlob().setContentType(MimeType.ZIP);
  const docx = Utilities.unzip(blob);
  const document = docx.filter(b => b.getName() == "word/document.xml");
  if (document.length == 0) return;
  const xml = document[0].getDataAsString();
  const root = XmlService.parse(xml).getRootElement();
  const n1 = root.getNamespace("w");
  const body = root.getChild("body", n1).getChildren("tbl", n1)
  const obj = body.map((e, i) => {
    const temp = {};
    const tblPr = e.getChild("tblPr", n1);
    if (tblPr) {
      const tblW = tblPr.getChild("tblW", n1);
      if (tblW) {
        const w = tblW.getAttribute("w", n1);
        if (w) {
          temp.tableWidth = Number(w.getValue()) / 20;  // Here, the unit of "dxa" is converted to "pt"
        }
      }
    }
    return temp;
  });
  if (obj.length > 0) console.log(obj);

  // DriveApp.getFiles()  // This is used for including the scope of `https://www.googleapis.com/auth/drive.readonly`.
}

Результат:

  • Когда ваша таблица извлекается с помощью этого сценария, извлекается tableWidth: 451.3. В данном случае это pt.
  • Индекс массива результатов означает индекс таблицы. Например, первая таблица в Google Document - 0.

Примечание:

  • В качестве подтверждения приведенного выше сценария, когда таблица создается с помощью сценария DocumentApp.getActiveDocument().getBody().appendTable([[""]]).getCell(0, 0).setWidth(200) и таблица извлекается с использованием приведенного выше примера сценария, я могу подтвердить, что был получен tableWidth: 200. Исходя из этой ситуации, считается, что размер таблицы в Google Document такой же, как и в данных DOCX.

Использованная литература:

person Tanaike    schedule 24.09.2020
comment
Большое спасибо Танаике. - person Rubén; 24.09.2020
comment
@ Рубен Добро пожаловать. И тебе спасибо. Я думаю, что этот метод приведет к обходным путям в различных ситуациях. Как и другие методы, использующие это, вы можете увидеть их на github.com/tanaikech/DocsServiceApp. - person Tanaike; 25.09.2020