Как я могу удалить белые фоновые слои экспорта pdf в скрипте google docs / google apps?

У меня проблема со скриптом приложений Google / документами Google. Я хотел сделать надстройку, которая добавляет водяной знак в документы Google docs с помощью API. Это работает нормально, но только если я помещаю водяной знак перед документом. Если я положу его за документ, водяной знак не будет виден. Затем я попытался посмотреть на разные слои в LibreOffice Draw и увидел, что в Google docs некоторые белые слои помещаются за текстом, которые находятся над водяным знаком.

Так кто-нибудь знает, как я могу экспортировать файл pdf из документов Google без белых слоев?

Я также попытался установить фон страницы на null или rgba(0,0,0,0.0) через скрипт приложений Google, например:

var highlightStyle = {};
highlightStyle[DocumentApp.Attribute.BACKGROUND_COLOR] = "rgba(0,0,0,0.0)";
let editedText = DocumentApp.getActiveDocument().getBody().editAsText().setAttributes(highlightStyle);

Но это не сработало.

Вот тестовый документ, где вы можете увидеть белые слои на заднем плане, как в офисном ящике libre.

Спасибо заранее.

Вот код плагина скрипта приложений Google:

    function base64Encode(str) {
    var encoded = Utilities.base64EncodeWebSafe(Utilities.newBlob(str).getBytes());
    return encoded.replace(/=+$/, '');
};

function encodeJWT(public, secret) {
    var header = JSON.stringify({
        typ: 'JWT',
        alg: 'HS256',
      jti: public
    });
    var encodedHeader = base64Encode(header);
    var iat = new Date().getTime() / 1000 - 60;
    var payload = JSON.stringify({
        iat: iat,
      iss: 'name',
      jti: public,
      public_key: public
    });
    var encodedPayload = base64Encode(payload);
    var toSign = [encodedHeader, encodedPayload].join('.');
    var signature = Utilities.computeHmacSha256Signature(toSign, secret);
    var encodedSignature = base64Encode(signature);
    return [toSign, encodedSignature].join('.');
};


function onInstall(){
  onOpen();
}

function onOpen(){
  let menu = DocumentApp.getUi().createAddonMenu().addItem("Merge PDFs", "showSidebar").addToUi();
}

let folderName = "watermark data";
let fileName = "watermark template";

function showSidebar(){
  var html = HtmlService.createTemplateFromFile("index").evaluate().setTitle("PDF Creator");
  
  DocumentApp.getUi().showSidebar(html);
}

function mergePdf(transparency){
  var highlightStyle = {};
  highlightStyle[DocumentApp.Attribute.BACKGROUND_COLOR] = "#ffffff";
  let editedText = DocumentApp.getActiveDocument().getBody().editAsText().setAttributes(highlightStyle);
  
  
  let folders = DriveApp.getFoldersByName(folderName);
  if(!folders.hasNext()){
    DriveApp.getRootFolder().createFolder(folderName) 
  }
  
  let files = DriveApp.getFilesByName(fileName);
  if(files.hasNext()){
    let header;
    if(DocumentApp.getActiveDocument().getHeader()){
      header = DocumentApp.getActiveDocument().getHeader();
    }else{
      header = DocumentApp.getActiveDocument().addHeader();
    }
    
  }
  fetchAPIData("https://api.ilovepdf.com/v1/auth", "post", {
    "public_key": "api_key"
  });
  

  let startData = JSON.parse(fetchAPIData("https://api.ilovepdf.com/v1/start/watermark", "get"));
  let uploadData1 = JSON.parse(requestAPI(convertPDF(), "https://" + startData.server + "/v1/upload", {
                                         "task": startData.task
                                         }));
    let file = DriveApp.getFilesByName(fileName + ".png");
  let file2 = DriveApp.getFilesByName(fileName + ".jpg");
  let file3 = DriveApp.getFilesByName(fileName + ".jpeg");
  if(file.hasNext()){
     file = file.next().getId();
  }else if(file2.hasNext()){
     file = file2.next().getId();
  }else if(file3.hasNext()){
     file = file3.next().getId();
  }else{
    DocumentApp.getUi().alert("Error, watermark not found!\n Please upload a watermark!");
  }
  let uploadData2 = JSON.parse(requestAPI(file, "https://" + startData.server + "/v1/upload", {
                                         "task": startData.task
                                         }));
//  DocumentApp.getUi().alert(typeof transparency);
  let processResponse = JSON.parse(fetchAPIData("https://" + startData.server + "/v1/process", "post",{
                                         "task": startData.task,
                                         "tool": "watermark",
                                         "files": [
                                         {
                                         "server_filename": uploadData1.server_filename,
                                         "filename": "Test"
                                         }                                       
                                         ],
                                         "mode": "image",
                                         "layer": "below",
                                         "image": uploadData2.server_filename,
                                                "transparency": transparency
                                         }));
  if(processResponse.status == "TaskSuccess"){
    let responseData = fetchAPIData("https://" + startData.server + "/v1/download/" + startData.task, "get");
    if(responseData){
      file = DriveApp.getRootFolder().createFile(responseData.getAs('application/pdf'));
      file.setName(DocumentApp.getActiveDocument().getName());
      DocumentApp.getUi().alert('You can download your pdf file here: ' + file.getDownloadUrl());
      var actionResponse = CardService.newActionResponseBuilder()
      .setOpenLink(CardService.newOpenLink()
                   .setUrl(file.getDownloadUrl())
                   .setOpenAs(CardService.OpenAs.FULL_SIZE)
                   .setOnClose(CardService.OnClose.NOTHING))
      .build();
    }else{
      DocumentApp.getUi().alert("Error, the API Request wasn't successful!");
    }
  }
}



function fetchAPIData(route, method, data){

  var options = {method: method};
  if(data){
    options = {
      'method' : method,
      'headers': {
        'Authorization': 'Bearer ' +  encodeJWT("api_key", "api_key")
      },
      'contentType': 'application/json',
      // Convert the JavaScript object to a JSON string.
      'payload' : JSON.stringify(data)
    };
  }else{
    options = {
      'method' : method,
      'headers': {
        'Authorization': 'Bearer ' +  encodeJWT("api_key", "api_key")
      }
    };
  }

  var response = UrlFetchApp.fetch(route, options); 
  return response;
}


function requestAPI(fileId, url, metadata) {
  var file = DriveApp.getFileById(fileId);
  var boundary = "name";
  var data = "";
  for (var i in metadata) {
    data += "--" + boundary + "\r\n";
    data += "Content-Disposition: form-data; name=\"" + i + "\"; \r\n\r\n" + metadata[i] + "\r\n";
  }
  data += "--" + boundary + "\r\n";
  data += "Content-Disposition: form-data; name=\"file\"; filename=\"" + file.getName() + "\"\r\n";
  data += "Content-Type:" + file.getMimeType() + "\r\n\r\n";
  var payload = Utilities.newBlob(data).getBytes()
    .concat(file.getBlob().getBytes())
    .concat(Utilities.newBlob("\r\n--" + boundary + "--").getBytes());
   var options = {
    method : "post",
    contentType : "multipart/form-data; boundary=" + boundary,
    payload : payload,
    muteHttpExceptions: true,
      'headers': {
        'Authorization': 'Bearer ' +  encodeJWT("api_key", "api_key")
      }
  };
  var res = UrlFetchApp.fetch(url, options).getContentText();

  Logger.log(res);
  return res;
}

function convertPDF() {
  doc = DocumentApp.getActiveDocument();
  var ui = DocumentApp.getUi();
    docblob = DocumentApp.getActiveDocument().getAs('application/pdf');
    /* Add the PDF extension */
    docblob.setName(doc.getName() + ".pdf");
    let file = DriveApp.getFoldersByName(folderName);
    if(!file.hasNext()){
      DriveApp.getRootFolder().createFolder(folderName) 
    }
    var files = DriveApp.getFilesByName(doc.getName() + ".pdf");
    while (files.hasNext()) {
      files.next().setTrashed(true);
    }
    file = DriveApp.getFoldersByName(folderName).next().createFile(docblob);
  return file.getId();
}

function saveFile(obj) {
    var files = DriveApp.getFilesByName(fileName + ".jpg");
    while (files.hasNext()) {
      files.next().setTrashed(true);
    }
    files = DriveApp.getFilesByName(fileName + ".png");
    while (files.hasNext()) {
      files.next().setTrashed(true);
    }
  var blob = Utilities.newBlob(Utilities.base64Decode(obj.data), obj.mimeType, fileName + "." + obj.mimeType.split("/")[1]);
  DocumentApp.getUi().alert("Watermark is uploaded successfully!");
  return DriveApp.getFoldersByName(folderName).next().createFile(blob).getId();
}

Я использую api водяного знака: ilovepdfapi

1 ответ

В итоге я удалил фон вручную:

  1. распаковать PDF с помощью любого подходящего инструмента (я использовал pdftk)

            pdftk source.pdf output decompressed.pdf decompress
    
  2. отредактируйте распакованный PDF-файл в любом ручном или автоматизированном текстовом редакторе (я использовал Vim)

    вы ищете блоки кода, которые выглядят так:

            1 1 1 RG 1 1 1 rg
    /G3 gs
    0 1123 794 1123 re
    f
    0 1123 794 1123 re
    f
    0 0 794 6738 re
    f
    

    то есть установка цвета фона на белый 1 1 1 rgа затем рисование одного или нескольких больших прямоугольников с заполненным фоном

    вы хотите удалить или прокомментировать ( %) все эти строки

  3. проверьте файл с помощью программы просмотра PDF и, при необходимости, повторно сожмите его:

            pdftk edited.pdf output final.pdf compress
    

Вот ссылка на справочник по языку в формате PDF . Просто используйте алфавитный указатель для поиска операторов, например reа также f, чтобы получить представление о том, что они делают.

Другие вопросы по тегам