[英]How to change the pivot table style from default blue to other colors using apache-poi
[英]How to change ppt presentation mode using apache-poi or another 3-rd library?
我一直在从事一个需要以“信息亭”演示模式显示PPT文件的项目。 在PPTX文件中,我可以将其像zip文件一样提取并重写presProps.xml,其中包含诸如“ p:showPr useTimings =” 0“ p:present”之类的属性,并且可以通过重写“ p:present”来更改模式。改为“ p:kiosk”。 我刚刚发现我可以使用apache-poi OPCPackage来做到这一点。 (例如, 如何使用ApachePoi编辑presProps.xml文件 )
但是,在PPT文件中,我无法像上面那样进行操作。 有什么方法可以更改PPT文件的显示模式。 还是可以使用apache-poi将PPT文件转换为PPTX文件,以便上述解决方案可以正常工作?
谢谢。
*.ppt
文件是以二进制文件格式存储的PowerPoint
文件。 这就是org.apache.poi.hslf的用途。 入口点是HSLFSlideShow 。
所有Office二进制格式的共同点是它们是Record
数据记录流以描述文档。 对于PowerPoint
,规格在此处: [MS-PPT]:PowerPoint(.ppt)二进制文件格式 。
根据您的要求,有一个DocumentContainer具有可选的SlideShowDocInfoAtom集。 可以设置F - fKioskMode (1 bit)
来设置信息亭模式。
可以通过HSLFSlideShow.getDocumentRecord使用apache poi
获取 DocumentContainer
。 但是随后apache poi
的支持终止了,因为到现在为止还没有实现Record
SlideShowDocInfoAtom
。
但是,使用扩展了RecordAtom
的自己的SlideShowDocInfoAtom
类,我们可以实现这一点。
例:
import java.io.FileOutputStream;
import java.io.FileInputStream;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.io.IOException;
import org.apache.poi.hslf.usermodel.*;
import org.apache.poi.hslf.record.Record;
import org.apache.poi.hslf.record.RecordAtom;
public class HSLFSlideShowToKioskMode {
// not really necessary, only for debug actions
private static void hexDumpRecord(Record record) throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
record.writeOut(out);
out.flush();
byte[] data = out.toByteArray();
out.close();
String hexDump = new java.math.BigInteger(data).toString(16);
System.out.println(hexDump);
}
// method for get/set SlideShowDocInfoAtom
private static SlideShowDocInfoAtom getSlideShowDocInfoAtom(HSLFSlideShow slideshow) throws Exception {
SlideShowDocInfoAtom slideShowDocInfoAtomRecord = null;
Record record = slideshow.getDocumentRecord().findFirstOfType(1025);
System.out.println(record.toString() + " type:" + record.getRecordType());
hexDumpRecord(record);
if (record != null) { // we must not create new SlideShowDocInfoAtom
// get present data
ByteArrayOutputStream out = new ByteArrayOutputStream();
record.writeOut(out);
out.flush();
byte[] data = out.toByteArray();
out.close();
// create new SlideShowDocInfoAtom from data
slideShowDocInfoAtomRecord = new SlideShowDocInfoAtom(data);
// replace old record with new SlideShowDocInfoAtom
slideshow.getDocumentRecord().addChildBefore(
slideShowDocInfoAtomRecord,
record
);
slideshow.getDocumentRecord().removeChild(record);
} else { // we must create new SlideShowDocInfoAtom
slideShowDocInfoAtomRecord = new SlideShowDocInfoAtom();
// add this SlideShowDocInfoAtom before EndDocumentAtom
slideshow.getDocumentRecord().addChildBefore(
slideShowDocInfoAtomRecord,
slideshow.getDocumentRecord().findFirstOfType(1002) // 1002 = 0x3ea = RT_EndDocumentAtom
);
}
return slideShowDocInfoAtomRecord;
}
public static void main(String[] args) throws Exception {
HSLFSlideShow slideshow = new HSLFSlideShow(new FileInputStream("Presentation.ppt"));
SlideShowDocInfoAtom slideShowDocInfoAtomRecord = getSlideShowDocInfoAtom(slideshow);
slideShowDocInfoAtomRecord.setfKioskMode(true);
slideShowDocInfoAtomRecord.setRestartTime(300000);
hexDumpRecord(slideShowDocInfoAtomRecord);
FileOutputStream out = new FileOutputStream("PresentationKiosk.ppt");
slideshow.write(out);
out.close();
slideshow.close();
}
//class SlideShowDocInfoAtom
//having methods for manipulating the [SlideShowDocInfoAtom](https://msdn.microsoft.com/en-us/library/dd908143.aspx)
private static class SlideShowDocInfoAtom extends RecordAtom {
private byte[] data;
public SlideShowDocInfoAtom() {
this.data = new byte[] {
//header
(byte)0x01, (byte)0x00, //MUST be 0x0001 (little endian)
(byte)0x01, (byte)0x04, //MUST be 0x0401 = RT_SlideShowDocInfoAtom (little endian)
(byte)0x50, (byte)0x00, (byte)0x00, (byte)0x00, //MUST be 0x00000050 (little endian)
//R //G //B //isRGB
(byte)0x00, (byte)0xFF, (byte)0x00, (byte)0xFE, //penColor green
(byte)0xe0, (byte)0x93, (byte)0x04, (byte)0x00, //restartTime 300000 ms (0x493e0, little endian)
(byte)0x00, (byte)0x00, //startSlide, only if fUseSlideRange is set
(byte)0x00, (byte)0x00, //endSlide, only if fUseSlideRange is set
//namedShow (64 bytes), only filled if there are named shows and fDocUseNamedShow is set, else all 0x00
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, //8
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, //16
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, //24
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, //32
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, //40
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, //48
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, //56
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, //64
//H G F E D C B A
//fLoopContinuously,fWillSkipNarration,fKioskMode,fBrowseMode,fDocUseNamedShow,fUseSlideRange,fWillSkipBuilds,fAutoAdvance
(byte)Integer.parseInt("00010000", 2), //only fBrowseMode is set
// I
//0,0,0,0,0,0,0,fHideScrollBar
(byte)Integer.parseInt("00000000", 2),
(byte)0x00, (byte)0x00 //unused
};
}
public SlideShowDocInfoAtom(byte[] data) {
this.data = data;
}
public void setfKioskMode(boolean on) {
byte HGFEDCBA = this.data[84];
HGFEDCBA &= (byte)Integer.parseInt("110011111", 2); //fKioskMode and fBrowseMode = 0
if (on) HGFEDCBA |= (byte)Integer.parseInt("10100000", 2); //fLoopContinuously = 1 and fKioskMode = 1
else HGFEDCBA |= (byte)Integer.parseInt("00010000", 2); //fBrowseMode = 1
this.data[84] = HGFEDCBA;
}
public void setRestartTime(long milliseconds) {
//must be greater than or equal 300000
if (milliseconds < 300000) return;
this.data[12] = (byte) (milliseconds & 0xFF);
this.data[13] = (byte) ((milliseconds >> 8) & 0xFF);
this.data[14] = (byte) ((milliseconds >> 16) & 0xFF);
this.data[15] = (byte) ((milliseconds >> 24) & 0xFF);
}
//TODO: other setters
@Override
public void writeOut(OutputStream out) throws IOException {
out.write(data);
}
@Override
public long getRecordType() { return 1025; }
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.