Проблема с изображениями в файлах PDF для ServletOutputStream - PullRequest
2 голосов
/ 22 декабря 2010

Я много искал, но не смог решить эту проблему. Я генерирую PDF файлы с помощью iText. Если я использую FileOutputStream, то все в порядке, но когда я пытаюсь использовать ServletOutputStream, изображения не отображаются в файлах PDF.

Когда я открывал файл PDF с помощью текстового редактора, я увидел, что там "???" так много. Это означает, что что-то бреет байты. Это все равно что пытаться использовать двоичные файлы с JSP. Но я использую JSF, Tomcat 6.0, Spring 3.0 и Richfaces.

Вот код, который генерирует PDF с ServletOutputStream и вызывает проблему

public static void saveChartToPDF(JFreeChart chart, String fileName, HttpServletResponse response) throws Exception {

ByteArrayOutputStream baos = new ByteArrayOutputStream();

Document document = new Document();
document.addCreationDate();
document.setPageSize(PageSize.A4.rotate());

PdfWriter writer = PdfWriter.getInstance(document, baos); 
document.open(); 

PdfContentByte cb = writer.getDirectContent(); 
PdfTemplate tp = cb.createTemplate(300, 300); 
Graphics2D g2 = tp.createGraphics(300, 300, new DefaultFontMapper()); 

Rectangle2D r2D = new Rectangle2D.Double(0, 0, 300, 300); 
chart.draw(g2, r2D, null); 
g2.dispose(); 
cb.addTemplate(tp, 0, 0); 

document.close(); 

response.setContentType("application/pdf");
response.setHeader("Expires", "0");
response.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");
response.setHeader("Pragma", "public");
response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".pdf");
response.setContentLength(baos.size());

ServletOutputStream out = response.getOutputStream();
baos.writeTo(out);
out.flush();

А вот код отлично работает с FileOutputStream ()

public static void saveChartToPDF(JFreeChart chart, String fileName, HttpServletResponse response) throws Exception {

Document document = new Document();
document.addCreationDate();
document.setPageSize(PageSize.A4.rotate());

PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream("c:/test1.pdf")); 

document.open(); 

PdfContentByte cb = writer.getDirectContent(); 
PdfTemplate tp = cb.createTemplate(300, 300); 
Graphics2D g2 = tp.createGraphics(300, 300, new DefaultFontMapper()); 

Rectangle2D r2D = new Rectangle2D.Double(0, 0, 300, 300); 
chart.draw(g2, r2D, null); 
g2.dispose(); 
cb.addTemplate(tp, 0, 0); 

document.close();

Я не мог найти, почему байты бреются.

Большое спасибо за вашу помощь,

1 Ответ

2 голосов
/ 23 декабря 2010

Когда вы полностью берете ответ в свои руки в JSF, вам нужно убедиться, что вы звоните

response.reset();

до того, как вы установите заголовки, а значит, мало шансов, что что-то уже было установлено / записаноответ (чаще чем какой-то пользовательский Filter).

Вы также должны убедиться, что вы вызываете

out.close();

вместо out.flush(), чтобы предотвратить любые другие байтывпоследствии будет записано в тело ответа.

Наконец, в JSF вам нужно вызвать

FacesContext.getCurrentInstance().responseComplete();

, чтобы JSF не перенаправлял запрос / ответ в представление (отображал ответ).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...