PDF出力を行うService
まさたかさんのアドバイスの元、Tapestry + iText上でPDF出力を行うServiceを実装してみた。
見よう見まねでできるのか不安だったが、それなりにすんなりできたみたいだ。
ソースコードはこんな感じ
Application仕様 <service name="pdf" class="pdfExample.PdfService"/>
サービスの実装 package pdfExample; import java.awt.Color; import java.io.ByteArrayOutputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; import javax.servlet.ServletException; import org.apache.tapestry.ApplicationRuntimeException; import org.apache.tapestry.IComponent; import org.apache.tapestry.IRequestCycle; import org.apache.tapestry.Tapestry; import org.apache.tapestry.engine.IEngineServiceView; import org.apache.tapestry.engine.ILink; import org.apache.tapestry.request.RequestContext; import org.apache.tapestry.request.ResponseOutputStream; import org.apache.tapestry.engine.AbstractService; import com.lowagie.text.Chunk; import com.lowagie.text.Document; import com.lowagie.text.DocumentException; import com.lowagie.text.Element; import com.lowagie.text.Font; import com.lowagie.text.HeaderFooter; import com.lowagie.text.PageSize; import com.lowagie.text.Paragraph; import com.lowagie.text.Phrase; import com.lowagie.text.pdf.BaseFont; import com.lowagie.text.pdf.PdfWriter; /** * @author Yusuke_k * */ public class PdfService extends AbstractService { public ILink getLink(IRequestCycle cycle, IComponent component, Object[] parameters) { if (Tapestry.size(parameters) != 1) throw new IllegalArgumentException( Tapestry.format("service-single-parameter", Tapestry.PAGE_SERVICE)); return constructLink(cycle, "pdf", new String[] {(String) parameters[0]}, null, true); } public void service( IEngineServiceView engine, IRequestCycle cycle, ResponseOutputStream output) throws ServletException, IOException { RequestContext context = cycle.getRequestContext(); String[] serviceContext = getServiceContext(context); if (Tapestry.size(serviceContext) != 1) throw new ApplicationRuntimeException( Tapestry.format("service-single-parameter", Tapestry.PAGE_SERVICE)); String pageName = serviceContext[0]; ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); Document document = new Document(PageSize.A4); try { // 出力先を指定し、文書をPDFとして出力 PdfWriter.getInstance(document, byteOut); document.addCreationDate(); document.addAuthor("TapestryWiki"); // 明朝体,ゴシック体フォントを設定 BaseFont mincho = BaseFont.createFont("HeiseiMin-W3", "UniJIS-UCS2-HW-H", false); BaseFont gothic = BaseFont.createFont("HeiseiKakuGo-W5", "UniJIS-UCS2-H", false); Font min10 = new Font(mincho, 10); Font goth10 = new Font(gothic, 10); // ヘッダー/フッターを設定 HeaderFooter header = new HeaderFooter( new Phrase( new Chunk( new SimpleDateFormat("yyyy年MM月dd日 - HH:mm:ss").format(new Date()), new Font(mincho, 10, Font.UNDERLINE) ) ), false ); header.setAlignment(Element.ALIGN_RIGHT); header.setBorderColor(Color.white); document.setHeader(header); HeaderFooter footer = new HeaderFooter( new Paragraph( "TapestryWiki", new Font(mincho, 12) ), false ); footer.setAlignment(Element.ALIGN_CENTER); document.setFooter(footer); // 出力開始 document.open(); // 文書に要素を追加 // --- タイトル Paragraph paragraphTitle = new Paragraph("pdfExample", new Font(gothic, 20)); paragraphTitle.setAlignment(Element.ALIGN_CENTER); document.add(paragraphTitle); // --- 本文 String text = "PDF Example."; document.add(new Paragraph(text, min10)); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (DocumentException e) { e.printStackTrace(); } // 出力終了 document.close(); // ブラウザへの出力 output.setContentType("application/pdf"); output.setBufferSize(byteOut.size()); output.write(byteOut.toByteArray()); } public String getName() { return "pdf"; } }
注意点としては、getName()が返す文字列と、アプリケーション仕様としてつける名前を一致させるようにすること。(この場合は"pdf")
後は、ブラウザ上からこんな感じでアクセスしてあげると良い。
http://localhost:8080/context/app?service=pdf/
最後のスラッシュの後にページ名をつけてあげたりして、指定のページをPDF出力してあげるようにすれば、実用化できそう。
おかげさまでTapestryのことをもっと知ることができました。ありがとうございますm(_ _)m > まさたかさん