Что делать если по работе приходит много договоров или счетов, все они в формате pdf и необходимо получать или редактировать из них определенные значения или параграф?
Можно пойти по обычному пути — найти онлайн конвертер, вручную загружать туда файлы и затем получать их текстовые аналоги из которых потом забирать всё необходимое. Схема рабочая, но долгая. А можно сделать проще — написать свой скрипт который получает pdf и забирает из него все нужное или конвертирует его в текст.
1. Подключаю Google Drive API
Так как надо будет создавать технический файл, который по сути заполняется «чем-то» из блоба, то стандартными средствами DriveApp написать конвертацию не получится. Для этого подключаю Google Drive API, которое позволяет это делать:
в результате получаю следующее:
2. Исходный pdf файл для конвертации
Как получать файлы и их свойства, я уже писал в статье ранее — Google Drive: начало работы с DriveApp.
Необходимо получить id требуемого файла. Это можно сделать двумя способами, через код:
function getFilesInFolder(){
const filesInFolderArr = []
const folder = DriveApp.getFolderById("FolderID")
const files = folder.getFiles();
while(files.hasNext()){
let file = files.next();
filesInFolderArr.push([[file.getName(), file.getId()]])
}
console.log(filesInFolderArr)
}
или через ссылку, в которой так же будет указан id конкретного файла:
В моем примере это pdf со сказкой Пушкина «Сказка о попе и о его работнике Балде».
Пример с массивом мне нравится больше, потому что потом каждый id из него можно использовать для автоматической обработки.
Итак, у меня есть pdf файл который надо конвертировать в текст.
3. Конвертация
function convertPDFToText(){
const fileId = "FileId"
const dirId = getFolderByFileId(fileId)
const workingDir = DriveApp.getFolderById(dirId)
const file = DriveApp.getFileById(fileId)
const { id, title } = Drive.Files.insert(
{
title: file.getName().replace(/\.pdf$/, ''),
mimeType: file.getMimeType() || 'application/pdf',
},
file.getBlob(),
{
ocr: true,
fields: 'id,title',
}
);
const textContent = DocumentApp.openById(id).getBody().getText();
DriveApp.getFileById(id).setTrashed(true);
workingDir.createFile(`${title}.txt`, textContent, 'text/plain');
}
где:
const fileId = "FileId"
— id pdf файла для конвертации;
const dirId = getFolderByFileId(fileId
) — вызов функции, которая определяет где именно находится файл:
function getFolderByFileId(targetId){
const file = DriveApp.getFileById(targetId)
const fileParents = file.getParents();
while ( fileParents.hasNext() ) {
let folder = fileParents.next();
return folder.getId()
}
}
const workingDir = DriveApp.getFolderById(dirId)
— папка где лежит pdf файл для конвертации и куда будет потом сохранен текстовый файл;
const file = DriveApp.getFileById(fileId)
— непосредственно сам pdf файл.
Вся магия Google Drive API творится здесь:
const { id, title } = Drive.Files.insert(
{
title: file.getName().replace(/\.pdf$/, ''),
mimeType: file.getMimeType() || 'application/pdf',
},
file.getBlob(),
{
ocr: true,
fields: 'id,title',
}
);
Drive.Files.insert
согласно описанию гугл драйв апи буквально вставляет новый файл на диск;
title: file.getName().replace(/\.pdf$/, '')
— получил имя исходного файла (для нового) и убрал из него расширение pdf;
mimeType: file.getMimeType() || 'application/pdf'
— описал формат файла;
file.getBlob()
— вставил в новый файл тот самый блоб исходного pdf файла;
ocr: true
— позволит конвертировать в текст;
const textContent = DocumentApp.openById(id).getBody().getText();
— получаю тело (текст) нового файла, открывая его по id — та самая переменная в const { id, title }
Собственно, уже здесь можно брать содержимое textContent
и парсить из него все необходимое регулярными выражениями.
DriveApp.getFileById(id).setTrashed(true);
— удаляю временный файл, созданный через Drive API;
workingDir.createFile(`${title}.txt`, textContent, 'text/plain');
— создаю текстовый файл в той же папке, в которой лежит исходный pdf файл:
где содержится ровно то же, что и в pdf:
4. Бонус: Очищаю корзину
Через DriveApp
в скриптах можно пометить файл как удаленным — .setTrashed(true)
— а вот очистить корзину уже нельзя.
Но так как подключен Drive API, чистить можно:
function clearTrash(){
Drive.Files.emptyTrash()
}