Экспорт таблиц Google Sheets в PDF файл

 

В данной статье я расскажу, как можно экспортировать таблицу Google в PDF файл, в заданном формате, используя Google Script. И еще отправим PDF файл на Google диск и на почту.

В Google таблицах есть возможность экспорта в PDF формате. Для это нужно зайти в меню Файл->Скачать->Документ PDF. Чтобы понять, как Google делает экспорт, воспользуемся браузерными инструментами разработчика. Откроем нужную нам таблицу и нажмем сочетание клавиш Ctrl+Shift+I(браузер Оперы или Google Chrome), и перейдем на вкладку Ethernet как на картинке ниже

Инструменты разработчика

Теперь сделаем экспорт в PDF через меню Google таблиц и найдем ссылку, которая отвечает за это действие

Ссылка для экспорта

Нажмем на ссылку и посмотрим параметры, которые передаются на сервер

Параметры форматирования для экспорта

На сервер передается идентификатор таблицы и три параметра: a, pc, gf. Для чего нужны a и gf я не знаю, а вот параметр pc – это все настройки выборки и форматирования для экспорта Google таблицы в PDF файл

Немного пришлось по ломать голову над значением 43745.64856909722, но так как я давно работаю с Delphi ответ пришел сам собой. Опытным путем я определил все необходимые настройки и вот что получилось:

На основе полученных данных можно сделать скрипт для экспорта содержимого Google таблиц в нужном нам формате. Для запуска скрипта сделаем дополнительный пункт меню в триггере onOpen.

Итого мы имеем три функции экспорта:

  • exportPDF – загрузка файла
  • exportPDFtoGDrive – отправка файла в Google диск, в ту же папку, где находится таблица
  • exportPDFtoEMail – отправка файла на электронную почту

И три функции myExportPDF, myExportPDFtoGDrive, myExportPDFtoEMail для примера использования.

Для указания данных и настройки форматирования передаются три параметра source, options и format. Эти параметры это части переменной pc, о которой я писал выше.

 
Поделиться:
0
Евгений Залепухин
16.01.2021 19:51
 
Здравствуйте, скопировал Ваш скрипт. запустил myExportPDFtoGDrive, файл сохранился, но там какой-то html. Что это может быть?
Показать полностью
5
Руслан Кандирал
16.01.2021 20:37
Евгений Залепухин
 
Здравствуйте!

Скопируйте ещё раз. Я исправил. Там в запросе добавилась переменная "esid", в других функциях я её добавил, а в экспорт на Google Drive нет.
Показать полностью
0
Сергей З.
03.12.2020 16:38
 
Здравствуйте! Очень нужная вещь. Но не могу понять почему отправляется только первая страница документа, а также не понимаю как убрать столбец с кнопками макросов. Вот что у меня.
Показать полностью
5
Руслан Кандирал
03.12.2020 22:16
Сергей З.
 
Здравствуйте, Сергей

По количеству страниц вы сделали правильно. Я проверил такой код:
У меня в PDF уходит два листа. Смотрите возможно ошибка в имени листа.
Что-бы кнопки не попадали в PDF, нужно указать границы экспорта для каждого листа

[sheet.getSheetId().toString(), // ID листа в виде строки
0, // начальная граница по вертикали (с первой строки)
160, // конечная граница по вертикали (по 160-ую строку включительно)
0, // начальная граница по горизонтали (с ячейки A)
8 // конечная граница по горизонтали (по ячейку H включительно)
]
Показать полностью
0
Тёма Ларионов
18.11.2020 09:21
 
Добрый день. Спасибо за очень функциональный код. Пользовался форматированием при отправке по почте , т.к. стандартная отправка не позволяет это делать. Все отлично работало до сегодняшнего дня. Похоже что то поменялось внутри гугла. Обнаружил, что в списке параметров a, pc, gf добавился еще один - lds. Добавил его в 'payload' но проблему это не решило. На почту по прежнему приходит html файл с именем filename.pdf внутри следующий текст: "Произошла ошибка. Попробуйте перезагрузить страницу или повторите попытку через несколько минут. Чтобы узнать больше о редакторах Google Документов, посетите наш Справочный центр Приносим извинения за доставленные неудобства. Команда Google Документов." Надеюсь что вы сможете мне помочь.
Показать полностью
5
Руслан Кандирал
18.11.2020 13:52
Тёма Ларионов
 
Здравствуйте!

Да, Вы правы, без этой переменной скрипт не срабатывает. Я так и не разобрался, что это за параметр, но как я понял это 64 битное значение в хексе, которое при каждой перезагрузке страницы меняется. Как показали тесты особо не важно какое значение в этой переменной, главное что-бы оно было. Я сделал так

/spreadsheets/d/"+ssID+"/pdf?esid="+(Math.round(Math.random()*10000000))+"&id="+ssID

То есть, подставляю произвольное значение и скрипт работает.
Показать полностью
0
Тёма Ларионов
18.11.2020 17:22
Руслан Кандирал
 
Я вбил статическое значение в эту переменную esid и тоже пока все работает. Тестировал под разными пользователями.
Показать полностью
0
Alexander Shevyakov
18.11.2020 17:28
Тёма Ларионов
 
Да, тоже заработало, спасибо!
Показать полностью
Комментарий удален
5
Руслан Кандирал
18.11.2020 16:16
Alexander Shevyakov
 
Обновил код в статье
Показать полностью
5
Руслан Кандирал
18.11.2020 15:37
Alexander Shevyakov
 
А какая разница, они же в списке переменных. Я тестировал и со скачиванием и с отправкой на почту.
Я обновлю код в статье, но позже. Сейчас какие-то проблемы на сервере. Может вечером или уже завтра утром.
Показать полностью
0
Тёма Ларионов
18.11.2020 11:25
Тёма Ларионов
 
Проблема обнаружилась в Request URL. Там добавился параметр esid. Теперь урл выглядит так:
doсs.google.com/spreadsheets/d/{tableID}/pdf?id={tableID}&esid={esid}
От чего зависит этот параметр пока не понимаю.
Показать полностью
0
Alexander Shevyakov
18.11.2020 12:47
Тёма Ларионов
 
Добрый день, у Вас получилось вренуть PDF? Я подставил esid - все равно приходит Html. Так же поигрался с классикой - getBlob() заменил на getAs("application/pdf") - тщетно
Показать полностью
0
Тёма Ларионов
18.11.2020 13:42
Alexander Shevyakov
 
Да, у меня все заработало после добавления esid в урл и параметра lds в payload. Но я работаю только с отправкой почтой.
Показать полностью
0
Alexander Shevyakov
18.11.2020 13:51
Тёма Ларионов
 
Что то типа такого:
const theBlob = UrlFetchApp.fetch("https://docs.google.com/spreadsheets/d/&...;, options).getBlob();
Показать полностью
0
Gianmarco Nizama Garc?a
16.10.2020 04:21
 
Привет! Спасибо, что поделились этим решением. У меня проблема. Это работает только при добавлении меню из самой таблицы расчетов. Если у меня есть веб-форма, я добавляю к ней кнопку и хочу экспортировать ее в pdf с помощью кнопки, появится сообщение:
Исключение: нельзя использовать SpreadsheetApp.getUi () из этого контекста. Я надеюсь, что вы можете мне помочь.
Показать полностью
5
Руслан Кандирал
16.10.2020 04:55
Gianmarco Nizama Garc?a
 
Здравствуйте!

Я не могу ответить на ваш вопрос, так как вы не предоставили достаточной информации о том как именно вызывается скрипт.

Проблема, скорее всего возникла при выполнении этого кода

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

Всё, что делает Javascript, это передаёт браузеру ссылку

Если у вас нет доступа к пользовательскому интерфейсу Google Sheets, то вам нужно найти другой способ как передать браузеру эту ссылку
Показать полностью
0
Gianmarco Nizama Garc?a
16.10.2020 05:45
Руслан Кандирал
 
На самом деле ошибка там, где она указывается. Опция правильно работает с той же таблицей, создав выпадающее меню. Но то, что я хочу сделать, - это кнопка в отдельном скрипте приложения, которая показывает веб-форму, и когда я нажимаю кнопку, я хочу, чтобы она экспортировала файл pdf уже определенной электронной таблицы.
https://script.google.com/macros/s/AKfyc...
Показать полностью
5
Руслан Кандирал
16.10.2020 06:05
Gianmarco Nizama Garc?a
 
Вым нужно сформировать ссылку экспорта таблицы в PDF
И передать эту ссылку веб-браузеру. Но не с помощью SpreadsheetApp.getUi().showModalDialog , а теми возможностями которые есть в вашей веб-форме.
Показать полностью
0
Gianmarco Nizama Garc?a
16.10.2020 07:16
Руслан Кандирал
 
Указанное я уже разместил, но, к сожалению, он ничего не экспортирует.



function myExportLink(){
var as = SpreadsheetApp.openById("1Y0cmIY2mUSzzGP01kjPDZoH-TQwr1FzAsmUOznNeBWY");
var sheet = as.getSheetByName('GRAFICOS');
exportLink(as.getId(), // Id de Tabla
[
[sheet.getSheetId().toString(), // ID de Hoja como cadena
0, // Borde vertical inicial (desde la primera l?nea)
160, // Borde vertical final (hasta la l?nea 160 inclusive)
0, // Borde horizontal inicial (desde la celda A)
8 // Borde del extremo horizontal (celda H incluida)
]
],
[
0, // Не показывать заметки
null,
1, // Показывать линии сетки
0, // Не показывать номера страниц
0, // Не показывать название книги
0, // Не показывать название листа
0, // Не показывать текущую дату
0, // Не показывать текущее время
1, // Повторять закрепленные строки
1, // Повторять закрепленные столбцы
1, // Порядок страниц вниз, затем вверх
1,
null,
null,
1, // Горизонтальное выравниване по левому краю
1 // Вертикальное выравнивание по верхнему краю
],
[
"A4", // Фрмат листа A4
1, // Ориентация страницы вертикальная
2, // Выровнять по высоте
1,
[
0.75, // Отступ сверху 0.75 дюймов
0.75, // Отступ снизу 0.75 дюймов
0.7, // Отступ слева 0.7 дюйма
0.7 // Отступ справа 0.7 дюйма
]
]
);
}


function exportLink(ssID,source,options,format){
var dt=new Date();
var d=encodeDate(dt.getFullYear(),dt.getMonth(),dt.getDate(),dt.getHours(),dt.getMinutes(),dt.getSeconds());
var pc=[null,null,null,null,null,null,null,null,null,0,
source,
10000000,null,null,null,null,null,null,null,null,null,null,null,null,null,null,
d,
null,null,
options,
format,
null,0,null,0];



return 'https://docs.google.com/spreadsheets/d/&...+"&gf=[]';
}
Показать полностью
5
Руслан Кандирал
16.10.2020 13:11
Gianmarco Nizama Garc?a
 
exportLink возвращает ссылку для экспорта. То есть эта функция не осуществляет экспорт, а только формирует ссылку для экспорта.

Я не видел вашего кода, я не знаю как и где вы хотите выполнить экспорт. По этому я не могу вам написать правильный код.

Если вы используете Google Forms, то скорее всего вам будет достаточно в функции exportPDF заменить SpreadsheetApp на FormApp
Показать полностью
0
Gianmarco Nizama Garc?a
17.10.2020 02:13
Руслан Кандирал
 
Большое спасибо. После нескольких попыток, исправлений и модификаций я наконец смог добиться того, чего хотел. Ваша информация и эта часть кода очень помогли мне, и я буду использовать ее в своем проекте. Еще раз спасибо за ваши прекрасные знания и вклад.
Показать полностью
0
Александр Александров
13.05.2020 14:56
 
Добрый день, Руслан.
Подскажите, пожалуйста, как конвертировать Google Sheets в Excel?
Спасибо.
Показать полностью
5
Руслан Кандирал
13.05.2020 16:53
Александр Александров
 
Здравствуйте, Александр!

Если в самом редактора, то меню "Файл"->"Скачать"->"Microsoft Excel"

Если через скрипт, то

[/code]
Показать полностью
0
Александр Александров
13.05.2020 17:09
Руслан Кандирал
 
Спасибо. Очень интересное решение!
Показать полностью
0
Евгения Токарева
05.04.2020 09:51
 
Добрый день, Руслан. Спасибо большое за код и инструкции! Есть вопрос: Как присвоить экспортированному файлу имя при простом скачивании PDF (functionName:"myExportPDF")? При экспорте на Drive и отправке по email я разобралась, как изменить имя (мне нужны были в имени файла дополнительно текущая дата и имя заказчика из определенной ячейки таблицы). А вот с myExportPDF не получилось.
Спасибо за Ваш труд!
Показать полностью
5
Руслан Кандирал
05.04.2020 10:32
Евгения Токарева
 
Здравствуйте, Евгения!

При экспорте в файл, имя формируется автоматически. Если экспортируется содержимое одного листа, то имя будет следующего вида
Имя книги - Имя листа.pdf
А если экспортируется содержимое из нескольких листов, то имя будет следующего вида
Имя книги.pdf
Если вы экспортируете данные из одно листа, то можно изменить имя этого листа и, соответственно, изменится название файла. Пример:
Показать полностью
0
Дмитрий Маркевич
23.03.2020 13:11
 
Добрый день.

Подскажите как сделать в одном PDF фале, что бы выгружались первые 10 строчек, потом пропустить 10 строчек, и остальные строчки.

Спасибо большое
Показать полностью
5
Руслан Кандирал
23.03.2020 14:28
Дмитрий Маркевич
 
Здравствуйте, Дмитрий

Брать отдельные выборки с одного листа не получится. Вы можете скрывать ненужные строки. Пример:
Но сразу же отобразить эти строки не получится. То есть код ниже отправит в PDF весь диапазон вместе со скрытыми строками
Показать полностью
0
Дмитрий Маркевич
23.03.2020 17:37
Руслан Кандирал
 
спасибо большое
Показать полностью
0
Dmitriy S
07.03.2020 17:04
 
Руслан, спасибо, очень полезный скрипт. А можно ли как-то сделать, что бы несколько листов экспортировались в PDF?
Показать полностью
5
Руслан Кандирал
07.03.2020 17:15
Dmitriy S
 
В параметр source передается информация о том, что именно выводить в PDF
В примере ниже источником будет выступать содержимое двух листов с именами "MySheetName" и "MySheetName2"

Показать полностью
0
Александр Макеев
05.12.2020 12:52
Руслан Кандирал
 
Руслан, добрый день! Спасибо огромное за данный кейс, очень помог автоматизировать один отчет из пяти листов, который нужно печатать группе людей!

Такой вопрос. Как сделать так, чтобы 4 листа документа экспортировать (по email) в вертикальной ориентации (как в примере), а 1 в горизонтальной. У меня получилось допилить скрипт под разбивку на два файла в одном сообщении, но я не могу применить форматирование, таким образом у меня приходят 2 одинаковых файла с разным неймингом.

я думаю, что нужно видоизменить функцию function exportPDFtoEMail, я там немного переделал, но на данный момент все испортил. Переменны theBlob не могу переделать так, чтобы брали избранные листы документа.

Заранее благодарю за подсказку!
Показать полностью
5
Руслан Кандирал
05.12.2020 15:01
Александр Макеев
 
Здравствуйте, Александр!

Показать полностью
0
Александр Макеев
05.12.2020 16:17
Руслан Кандирал
 
Отлично работает! Спасибо огромное за помощь!
Показать полностью
0
Dmitriy S
08.03.2020 02:27
Руслан Кандирал
 
Руслан, огромное спасибо, все супер... Еще один вопрос, а масштаб где-то можно выставить, что бы весь выделенный диапазон помещался на лис? или это автоматом?
Показать полностью
0
Руслан Кандирал
08.03.2020 06:56
Dmitriy S
 
В параметре format третье и четвертое значения отвечаю за масштаб
Третье значение указывает на метод масштабирования:
1) 100%
2) Выровнять по ширине
3) Выровнять по высоте
4) Выровнять по размеру страницы
5) Пользовательский масштаб

Четвертое значение необходимо если в предыдущем значении указано пользовательское масштабирование. Тут мы указываем коэффициент масштабирования с точностью до двух знаков после точки. Например: 50%->0.5, 25%->0.25, 200%->2

В примере ниже устанавливается масштаб по ширине листа
В примере ниже устанавливается масштаб 50%
Показать полностью
0
Dmitriy S
08.03.2020 21:31
Руслан Кандирал
 
вот параметр format ["A4",1,2,1,[0.75,0.75,0.7,0.7]]
Не совсем понятно А4 - 100% или я не туда смотрю?

Раньше писали:
[
"A4", // Фрмат листа A4
1, // Ориентация страницы вертикальная
2, // Выровнять по высоте
1,
[
0.75, // Отступ сверху 0.75 дюймов
0.75, // Отступ снизу 0.75 дюймов
0.7, // Отступ слева 0.7 дюйма
0.7 // Отступ справа 0.7 дюйма
]
]

Или в Этом параметре ["A4",1,2,1,[0.75,0.75,0.7,0.7]] нужно 2 заменить на 4 и это будет Выровнять по размеру страницы?

Просто слово ВЫРОВНЯТЬ не совсем понятно в контексте МАСШТАБА...
Если это масштабирование то тогда УМЕСТИТЬ или ВПИСАТЬ или ПОДОГНАТЬ в ширину страницы... По этому я и запутался...
Показать полностью
5
Руслан Кандирал
08.03.2020 21:53
Dmitriy S
 
Да, двойка это и есть параметр, который может принимать пять значений описанных в моём предыдущем комментарие. А следующее значение это произвольный масштаб
Показать полностью
0
Dmitriy S
09.03.2020 03:30
Руслан Кандирал
 
Огромное спасибо... все разобрал... работает...
Показать полностью
0
Евгений Сакин
03.01.2020 18:45
 
Руслан,подскажи пожалуйста,что в этом коде поменять,что бы печаталась не активная страница,а допустим первая?Например:я нахожусь на листе5,а нужно что бы отпечатался лист 1.
Показать полностью
5
Руслан Кандирал
03.01.2020 19:09
Евгений Сакин
 
Измените строку
var sheet=as.getActiveSheet();
на
var sheet=as.getSheetByName("MySheetName");
Где MySheetName - название нужного листа
Показать полностью
0
Евгений Сакин
03.01.2020 19:16
Руслан Кандирал
 
Спасибо большое!Все получилось.
Показать полностью
0
Евгений Сакин
02.01.2020 19:42
 
Приветствую!Отличная работа.А подскажи,возможно ли сделать так,что бы таблица экспортировалась в файл в формате jpeg?
Показать полностью
5
Руслан Кандирал
02.01.2020 20:25
Евгений Сакин
 
Здравствуйте! В Google таблицах экспорта в картинку нет. Может возможно с помощью скрипта каким-то образом преобразовать pdf в изображение, но я с этим еще не сталкивался.
Показать полностью
0
Евгений Сакин
02.01.2020 22:15
Руслан Кандирал
 
Так вот я и думаю,что нужно скриптом.Но со скриптами я не очень.Макрос там какой то записать,это можно.Ну вобщем буду следить за Вашими новыми проектами.Удачи вам и 100к подписчиков на канал!
Показать полностью

Новости сайта

05.05.2020 15:34
Новая статья про удаленное управление принтером Domino V-series
Реализация протокола передачи данных для связи с термотрансферным принтером Domino V-series из Delphi
24.04.2020 22:14
Добавлена статья по работе с сенсором Omron FQ-CR1 из Delphi
Подключение по сети к считывателю штрих-кодов Omron FQ-CR1 из программы на Delphi
17.03.2020 20:46
Обновлен пакет компонентов для Delphi
Доступна для скачивания новая версия компонентов для Delphi, от 17.03.2020г. С данной версии библиотеки доступны и на GitHub
28.01.2020 16:15
Опубликована статья о принципе работы коннекторов в Delphi
Коннектор – это объект, осуществляющий связь с внешними объектами(объектом). Внешним объектом может выступать другая программа или другое устройство, которое поддерживает тот же интерфейс или протокол связи.

Популярные статьи

Инструкция по установке компонентов на Delphi
Подробная инструкция по установке компонентов на Delphi с видео обзором
Экспорт таблиц Google Sheets в PDF файл, на email и на Google диск
Экспорт таблиц Google Sheets в PDF файл с помощью Google Script с последующим скачиванием или сохранением на Google Drive или отправкой на почту
Modbus Slave на Arduino
Реализация клиентской части протокола Modbus RTU и Modbus ASCII для контроллеров Arduino
Пример передачи данных по протоколу Modbus на Delphi
Пример передачи данных с контроллера ОВЕН ПЛК100 в программу на Delphi по протоколу Modbus