У меня есть веб-приложение, которое использует пару форм PDF для создания документов объемом до 500 страниц;каждая форма представляет собой одну страницу и имеет 40-50 полей.Законченный документ предназначен только для отображения и печати, поэтому нет необходимости сохранять аспект заполнения формы PDF при создании документа.
У меня есть рабочий код с использованием iText 1.4.5;он создает эти документы менее чем за 30 секунд (websphere, MVS), что хорошо для моих целей.
Приложение действительно использует значительный объем памяти, и недавно привело к сбою сервера.Меня интересует, могу ли я изменить существующий код, чтобы сохранить большинство его атрибутов и использовать значительно меньше памяти.Мне кажется, что должно быть возможным, учитывая, что объем используемой памяти указывает на то, что весь документ находится в памяти до завершения, и моя логика не нуждается в этом - после заполнения страницы моя программас этим можно было записать диск и освободить любую память, связанную только с этой страницей.
Я нашел ссылку на метод com.lowagie.text.pdf.PdfWriter.freeReader (), но не уверен, как использовать его в моей среде.Мой вопрос заключается в том, приведет ли это к тому, что моя программа будет использовать меньше памяти (за один раз) и куда будет помещен вызов.
Я создаю объекты iText Document, PdfWriter и PdfReader следующим образом:
public PdfFormFiller(String givenInputSpecification,
Document givenDocument,
PdfWriter givenWriter)
{
// instance fields stored for PDF or tracking purposes.
inputSpecification = givenInputSpecification;
document = givenDocument;
writer = givenWriter;
contentByte = writer.getDirectContent();
// 'DirectContentUnder' is a contentByte object that allows
// our app to write out document content that appears
// underneath things written to the DirectContentOver; i.e.,
// this is a layer underneath some other things.
underContent = writer.getDirectContentUnder();
try
{
PdfReader reader = new PdfReader(inputSpecification);
template = writer.getImportedPage(reader, 1); // this line limits us to 1-page forms;
AcroFields aFields = reader.getAcroFields(); // the fields on the form.
<<more stuff in this constructor, deleted from here>>
Я заполняю значения в форме, используя это:
/**
* * 'Fill' this given form with the given data values, i.e., write the given data
* values onto the positions in the forms corresponding to their field names.
* @param fieldValueMap a map with each key the name
* of the data field, and each value the string to be put on
* the form for that field.
*/
public void fillForm(Map fieldValueMap) throws DocumentException
{
Iterator keys = fieldValueMap.keySet().iterator();
while (keys.hasNext())
{
String fieldName = (String)keys.next();
FormField formField = (FormField)fields.get(fieldName);
String value = null;
if (fieldName != null)
{
value = (String)fieldValueMap.get(fieldName);
}
if (null != value && null != formField)
{
fillField(formField, value);
}
}
// add the template of the form; the fact that it is added
// to "underContent" causes iText to put it in a list if it's
// not already there, so it only gets added once per doc.
underContent.addTemplate(getTemplate(), 0, 0);
// start a new page - throws DocumentException
document.newPage();
}
И я записываю значение в поле, используя это:
/**
* fills the given field with the given value
* @param formField field and attributes
* @param value String value
*/
private void fillField(FormField formField, String value) throws DocumentException
{
if (formField.fieldType == AcroFields.FIELD_TYPE_CHECKBOX)
{
if (value.substring(0,1).equalsIgnoreCase("Y")) { value = "X"; }
else { value = " "; }
}
ColumnText columnText = new ColumnText(contentByte);
<<excised code determining fontToUse>>
setSimpleColumn(columnText, value, fontToUse, formField.box,
leading, Element.ALIGN_LEFT, false);
}
'setSimpleColumn ()' - это вялостьрутинная обработка подгонки текста в прямоугольник на форме.
private int setSimpleColumn(ColumnText columnText, String value, Font fontToUse,
Rectangle box, int leading, int alignment, boolean simulate)
throws DocumentException
{
columnText.setSimpleColumn(new Phrase(value, fontToUse),
box.left(), box.bottom(),
box.right(), box.top(),
leading, alignment
);
int result = columnText.go(simulate);
return result;
}
Итак, опять же, два основных вопроса: поможет ли PdfWriter.freeReader () освободить память, которая в противном случае удерживается до завершения документа, и (2) куда мне обратитьсяэто?
Если кто-то хочет рассказать мне, как делать многостраничные формы, меня это тоже интересует ...