Как переименовать мастер слайдов

Он уже работает по назначению, проблема в том, что Date.toString «помогает» преобразовать внутреннюю метку времени в ваш местный часовой пояс. Использование Date.toGMTString приведет к тому же самому методу времени для каждого из значений.

Если результирующая временная метка неверна, проблема заключается в создании экземпляра Date. Использование конструктора типа new Date(2018, 7, 11, 15, 45, 11) приведет к вычислению этой даты для системного часового пояса, а не UTC. Чтобы создать его для UTC, есть Date.UTC, но все эти API были устаревшими с Java 1.1, потому что они настолько запутывают.

0
задан Axel Richter 19 January 2019 в 11:15
поделиться

1 ответ

В PowerPoint презентации мастер назван так, как его тема. Мы можем получить все мастера, используя XMLSlideShow.getSlideMasters . XSLFSlideMaster расширяется XSLFSheet. Таким образом, мы можем получить тему каждого мастера, используя XSLFSheet.getTheme . Как только у нас есть XSLFTheme , для имени появляются геттеры и сеттеры.

Пример:

import java.io.FileInputStream;
import java.io.FileOutputStream;

import org.apache.poi.xslf.usermodel.*;

public class XSLFRenameMasterTheme {

 public static void main(String[] args) throws Exception {

  XMLSlideShow slideshow = new XMLSlideShow(new FileInputStream("Presentation.pptx"));

  for (XSLFSlideMaster master : slideshow.getSlideMasters()) {
   XSLFTheme theme = master.getTheme();
   String name = theme.getName();
System.out.println(name);
   theme.setName(name + " renamed");
System.out.println(theme.getName());
  }

  FileOutputStream out = new FileOutputStream("PresentationRenamedMaster.pptx");
  slideshow.write(out);
  out.close();
  slideshow.close();
 }
}

Для HSLFSlideShow кажется, что нет доступа к поддерживаемым именам мастеров. Можно получить HSLFSlideMaster с, но не их имена.

Так что, если, тем не менее, нужно это сделать, то нужно знать о внутренностях двоичной файловой системы *.ppt. Это описано в [MS-PPT]: формат двоичных файлов PowerPoint (.ppt) . Имена листов находятся в SlideNameAtom . Обладая знаниями о внутренностях, можно создать класс для такой записи. Это может обеспечить методы для получения и установки имени.

Пример:

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.io.IOException;
import java.io.ByteArrayOutputStream;

import org.apache.poi.hslf.usermodel.*;
import org.apache.poi.hslf.record.Record;
import org.apache.poi.hslf.record.RecordAtom;

import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.StringUtil;

public class HSLFRenameMaster {

 // method for get SlideNameAtom out of the master
 private static SlideNameAtom getSlideNameAtom(HSLFSlideMaster master) throws Exception {
  SlideNameAtom slideNameAtomRecord = null;
  Record record = master.getSheetContainer().findFirstOfType(0x0FBA);
  if (record != null) { // SlideNameAtom exists
   // get present data
   ByteArrayOutputStream out = new ByteArrayOutputStream();
   record.writeOut(out);
   out.flush();
   byte[] data = out.toByteArray();
   out.close();
   // create new SlideNameAtom from data
   slideNameAtomRecord = new SlideNameAtom(data);
   // replace old record with new SlideNameAtom
   master.getSheetContainer().addChildBefore(
    slideNameAtomRecord,
    record
   );
   master.getSheetContainer().removeChild(record);
  } 
  return slideNameAtomRecord;
 }


 public static void main(String[] args) throws Exception {

  HSLFSlideShow slideshow = new HSLFSlideShow(new FileInputStream("Presentation.ppt"));

  for (HSLFSlideMaster master : slideshow.getSlideMasters()) {
   SlideNameAtom slideNameAtomRecord = getSlideNameAtom(master);
   if (slideNameAtomRecord != null) {
    String name = slideNameAtomRecord.getName();
System.out.println(name);
    slideNameAtomRecord.setName(name + " renamed");
System.out.println(slideNameAtomRecord.getName());
   }
  }

  FileOutputStream out = new FileOutputStream("PresentationRenamedMaster.ppt");
  slideshow.write(out);
  out.close();
  slideshow.close();
 }

 //class SlideNameAtom 
 //having methods for manipulating the [SlideNameAtom](https://msdn.microsoft.com/en-us/library/dd906297(v=office.12).aspx)
 private static class SlideNameAtom extends RecordAtom {

  private byte[] data;
  private String name;

  public SlideNameAtom() {
   this.name = "Office";
   setName(name);
  }

  public SlideNameAtom(byte[] data) {
   this.data = data;
   this.name = getName();
  }

  public void setName(String name) {
   this.name = name;
   int length = 8;
   length += StringUtil.getToUnicodeLE(name).length;
   this.data = new byte[length];
   data[0] = (byte)0x20; data[1] = (byte)0x00; 
   data[2] = (byte)0xBA; data[3] = (byte)0x0F; //MUST be 0x0fba = RT_CString (little endian)
   LittleEndian.putInt(data, 4, StringUtil.getToUnicodeLE(name).length);
   StringUtil.putUnicodeLE(name, data, 8);
  }

  public String getName() {
   return StringUtil.getFromUnicodeLE(this.data, 8, (this.data.length-8)/2);
  }

  @Override
  public void writeOut(OutputStream out) throws IOException {
   out.write(data);
  }

  @Override
  public long getRecordType() { return 0x0FBA; }
 }

}

Вопрос в том, стоит ли переименование мастера.

0
ответ дан Axel Richter 19 January 2019 в 11:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: