Как переименовать мастер слайдов - PullRequest
0 голосов
/ 19 января 2019

Я хочу переименовать мастер слайдов PowerPoint с помощью apache poiPowerPoint GUI мы делаем View - Slide Master - тогда мы щелкаем правой кнопкой мыши самый верхний слайд слева и выбираем Rename Master из контекстного меню.

enter image description here

1 Ответ

0 голосов
/ 19 января 2019

В презентации 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 s, но не их имена.

Так что, если вам все же нужно это сделать, тогда вы должны знать о внутренностях двоичной файловой системы *.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; }
 }

}

Вопрос в том, стоит ли переименование мастера этого усилия.

...