FileDocCategorySizeDatePackage
QuickButCruddyTextExtractor.javaAPI DocApache Poi 3.0.17168Mon Jan 01 18:55:34 GMT 2007org.apache.poi.hslf.extractor

QuickButCruddyTextExtractor

public class QuickButCruddyTextExtractor extends Object
This class will get all the text from a Powerpoint Document, including all the bits you didn't want, and in a somewhat random order, but will do it very fast. The class ignores most of the hslf classes, and doesn't use HSLFSlideShow. Instead, it just does a very basic scan through the file, grabbing all the text records as it goes. It then returns the text, either as a single string, or as a vector of all the individual strings. Because of how it works, it will return a lot of "crud" text that you probably didn't want! It will return text from master slides. It will return duplicate text, and some mangled text (powerpoint files often have duplicate copies of slide text in them). You don't get any idea what the text was associated with. Almost everyone will want to use @see PowerPointExtractor instead. There are only a very small number of cases (eg some performance sensitive lucene indexers) that would ever want to use this!
author
Nick Burch

Fields Summary
private POIFSFileSystem
fs
private InputStream
is
private byte[]
pptContents
Constructors Summary
public QuickButCruddyTextExtractor(String fileName)
Creates an extractor from a given file name

param
fileName

		this(new FileInputStream(fileName));
	
public QuickButCruddyTextExtractor(InputStream iStream)
Creates an extractor from a given input stream

param
iStream

		this(new POIFSFileSystem(iStream));
		is = iStream;
	
public QuickButCruddyTextExtractor(POIFSFileSystem poifs)
Creates an extractor from a POIFS Filesystem

param
poifs

		fs = poifs;

		// Find the PowerPoint bit, and get out the bytes
		DocumentEntry docProps =
			(DocumentEntry)fs.getRoot().getEntry("PowerPoint Document");
		pptContents = new byte[docProps.getSize()];
		fs.createDocumentInputStream("PowerPoint Document").read(pptContents);
	
Methods Summary
public voidclose()
Shuts down the underlying streams

		if(is != null) { is.close(); }
		fs = null;
	
public intfindTextRecords(int startPos, java.util.Vector textV)
For the given position, look if the record is a text record, and wind on after. If it is a text record, grabs out the text. Whatever happens, returns the position of the next record, or -1 if no more.

		// Grab the length, and the first option byte
		// Note that the length doesn't include the 8 byte atom header
		int len = (int)LittleEndian.getUInt(pptContents,startPos+4);
		byte opt = pptContents[startPos];

		// If it's a container, step into it and return
		// (If it's a container, option byte 1 BINARY_AND 0x0f will be 0x0f)
		int container = (int)opt & 0x0f;
		if(container == 0x0f) {
			return (startPos+8);
		}

		// Otherwise, check the type to see if it's text
		long type = LittleEndian.getUShort(pptContents,startPos+2);
		TextRun trun = null;

		// TextBytesAtom
		if(type == RecordTypes.TextBytesAtom.typeID) {
			TextBytesAtom tba = (TextBytesAtom)Record.createRecordForType(type, pptContents, startPos, len+8);
			trun = new TextRun((TextHeaderAtom)null,tba,(StyleTextPropAtom)null);
		}
		// TextCharsAtom
		if(type == RecordTypes.TextCharsAtom.typeID) {
			TextCharsAtom tca = (TextCharsAtom)Record.createRecordForType(type, pptContents, startPos, len+8);
			trun = new TextRun((TextHeaderAtom)null,tca,(StyleTextPropAtom)null);
		}
		
		// CString (doesn't go via a TextRun)
		if(type == RecordTypes.CString.typeID) {
			CString cs = (CString)Record.createRecordForType(type, pptContents, startPos, len+8);
			String text = cs.getText();
			
			// Ignore the ones we know to be rubbish
			if(text.equals("___PPT10")) {
			} else if(text.equals("Default Design")) {
			} else {
				textV.add(text);
			}
		}

		// If we found text via a TextRun, save it in the vector
		if(trun != null) {
			textV.add(trun.getText());
		}
		
		// Wind on by the atom length, and check we're not at the end
		int newPos = (startPos + 8 + len);
		if(newPos > (pptContents.length - 8)) { 
			newPos = -1;
		}
		return newPos;
	
public java.lang.StringgetTextAsString()
Fetches the ALL the text of the powerpoint file, as a single string

		StringBuffer ret = new StringBuffer();
		Vector textV = getTextAsVector();
		for(int i=0; i<textV.size(); i++) {
			String text = (String)textV.get(i);
			ret.append(text);
			if(! text.endsWith("\n")) {
				ret.append('\n");
			}
		}
		return ret.toString();
	
public java.util.VectorgetTextAsVector()
Fetches the ALL the text of the powerpoint file, in a vector of strings, one per text record

		Vector textV = new Vector();

		// Set to the start of the file
		int walkPos = 0;

		// Start walking the file, looking for the records
		while(walkPos != -1) {
			int newPos = findTextRecords(walkPos,textV);
			walkPos = newPos;
		}

		// Return what we find
		return textV;
	
public static voidmain(java.lang.String[] args)
Really basic text extractor, that will also return lots of crud text. Takes a single argument, the file to extract from

		if(args.length < 1) {
			System.err.println("Useage:");
			System.err.println("\tQuickButCruddyTextExtractor <file>");
			System.exit(1);
		}

		String file = args[0];

		QuickButCruddyTextExtractor ppe = new QuickButCruddyTextExtractor(file);
		System.out.println(ppe.getTextAsString());
		ppe.close();