- 背景
公司因人员变动和业务整改,提出将原打印(数据库保存的HTML字符串做替换)全部迁移至framework(利用framework完成数据字段替换与EL表达式相似,转换成PDF的二进制流返回),主要是为了方便开发和维护,对应单个的打印文件的预览都没有问题,后期提出新需求,需要勾选多个预览文件时,在一个弹框里面看到所有的pdf文件,就是一个接着一个的长pdf。
特别说明:所有打印文件的模板(framework文件)全部存在后端。 - 思路
1. 对返回的多个PDF流,得到对应的多个二进制数组
2.将得到的二进制数组组合成一个
3.将最终得到的二进制数组,outputStream.write(byte[])写回 - 历程
1.直接拼接得到的二进制数组可以正确写回,但是只显示第一个完整的PDF文件
原因:文件流有对应的开始结束标志,如:%%EOF
2.以为只要删掉除最后一个文件流(二进制数组)中标识“%%EOF”的内容就可以了,然而不只是这几个字,仍然只显示第一个文件的内容
原因:仔细查看写回的流,发现每一个文件流都有一个很长的头部数据和尾部数据,标志着一个完整的文件(可查看最后的参考流),这里面包含着规则,想要通过删除特定标志字符这种方式拼接PDF文件,不易实现,个人此时也觉得想着这种涉及到底层实现的又比较实用的操作,应该会有工具类来帮助我们实现,通过搜索发现了 PDFMergerUtility
3.PDFMergerUtility 合并多个PDF文件OutputStream os = response.getOutputStream(); // apache 提供用于 多个pdf 合并的工具类 PDFMergerUtility pdfMergerUtility = new PDFMergerUtility(); for (String param : params) { // 业务返回 ByteArrayOutputStream stream = service.export(param1, param); byte[] streamByteArr = stream.toByteArray(); ByteArrayInputStream inputStream = new ByteArrayInputStream(streamByteArr); // 添加 pdf 数据源 pdfMergerUtility.addSource(inputStream); inputStream.close(); } // 也可以指定要合成的文件和合成后存储的文件位置 //pdfMergerUtility.setDestinationFileName("F:\\desk\\1company\\result.pdf"); OutputStream outputStream = new ByteArrayOutputStream(); // 指定目标文件输出流 pdfMergerUtility.setDestinationStream(outputStream); pdfMergerUtility.mergeDocuments(null); // 获取合并后的目标数据流 ByteArrayOutputStream mergerUtilityDestinationStream = (ByteArrayOutputStream) pdfMergerUtility.getDestinationStream(); mergerUtilityDestinationStream.writeTo(os); outputStream.close(); os.close();
- 终章
PDFMergerUtility
Apache 提供的一个用于合并多个PDF文件成一个的工具类
API 参考
可能是个人流操作用得不是很频繁,所以一开始解决起来有些天真,个人觉得应该还是可以通过一些流操作代码自己实现多个文件的合并,希望在评论区得到各位的指点 - 写回的流数据参考
%PDF-1.4 %���� 4 0 obj <</Filter/FlateDecode/Length 6544>>stream //头部 M2C<9~;i�}�bė�9��)U��a�I2�$oMr��yR=NN��7'[4����ɔF�(W�|1�S�G����!�s,c�z���}+>&�:��@�]���w�T���#9V����M���Ʊ�Ǜ���$��MT��r>�s����ڽ�t�.xܶS$+���7�����Ӽ�i_�N�|C��w�q�v�cC��4�~: endstream //尾部 endobj 7 0 obj <</Descent -140/CapHeight 699/StemV 80/Type/FontDescriptor/FontFile2 6 0 R/Flags 32/FontBBox[0 -140 996 855]/FontName/ABRONC+SimSun/ItalicAngle 0/Ascent 859>> endobj 8 0 obj <</DW 1000/Subtype/CIDFontType2/CIDSystemInfo<</Supplement 0/Registry(Adobe)/Ordering(Identity)>>/Type/Font/BaseFont/ABRONC+SimSun/FontDescriptor 7 0 R/W [3[500]8[500]11[500 500]16[500]18[500 500 500 500 500 500 500 500]27[500 500 500]33[500]38[500 500 500 500]44[500]48[500 500]51[500]53[500 500 500]57[500]59[500]79[500 500]22021[500]]/CIDToGIDMap/Identity>> endobj 9 0 obj <</Filter/FlateDecode/Length 1223>>stream x�]��j�7����L�Jm^d � �j4��ݴ��>�S��m�����T�ݏ?=\���w��^ۗ�~�ϗ~o��6�u<=_Nڜ�s{߿��R���5�����xy�������������������?��Ow����=_���̟-������x���:�|�c��~)�_��8�a�W���:���X�^�x��6n��4N�j}����O�ҿ�[+%���:��FeH14$R�M��&A�*4]$��)�Z�Q�|�j�(�F$�Z+R�� v�X�S>h�HpEh�! W�v;��A[ ��!,:���"��L���eR>��.#��aU>�$�V�N��6$���|�$���$�Z Hb�M� �]V"����|�7H��AS5���p�t��S#�v�(� ��v�(� �JtC���țnT��tS�TB�@7%����n��1 �lNp�#H:8�f�\R�y-�t%�j�\R #&V�8��@2r�"LɈ�I�� Y�¤f�\�J�� ����M�yL��$۵HU0��Q5o. ֧ƕ�S$�j5e���<�a��P��r�@rj�}�7���0�a�m���ۣs�@JʉT��`�t�Zp���R��Y�ڬ$��3�u0y�j"QޤZ�H1o.�A6oRS/m�'��"&��˃�;��l�P\��q��@�ҎKRH������H#o҈R(y�F�#Hs︒��$��!pIX���izL���&�I�f͛�;�|�Q�W ����h�>� z�v�#�m��D�S�ĺ���t�z��+��*z0�M��AO�F��� ��p�@�}u�^)�]N$ ��������]G�\�zh������S$� g�h��B_=�Ř��[����['H�+m�6�H-o.�w4����wtc� ���p'���r��+�B?���u�6�NJ�h��0� ��7�S\��L���������� ��w3�/�O��&�:3�� aH�0�l�6�d��Zn3T ^��[�*p3�ʅ`]X�(�ah4֭���`�,9^�c-�!F�@[_xU�Qe�ͨ:vL|����c7[a�h�v$^����Ns�Ɗ.�V��f�Ɖ���x��NV��i�*W�0��U�0�7�:�0b�&L)�^�T"?5��[�fd��+RE����[����Ӻ}�n�Ս�<����~���}������C�� endstream endobj 3 0 obj <</Subtype/Type0/Type/Font/BaseFont/ABRONC+SimSun/Encoding/Identity-H/DescendantFonts[8 0 R]/ToUnicode 9 0 R>> endobj 1 0 obj <</Subtype/Form/Filter/FlateDecode/Type/XObject/Matrix [1 0 0 1 0 0]/FormType 1/Resources<</ProcSet [/PDF /Text /ImageB /ImageC /ImageI]/Font<</F1 3 0 R>>>>/BBox[0 0 50 50]/Length 39>>stream x�s ��w3T04RI��``fa`�����r ��� Xk� endstream endobj 5 0 obj <</Kids[2 0 R]/Type/Pages/Count 1/ITXT(2.1.7)>> endobj 10 0 obj <</Type/Catalog/Pages 5 0 R>> endobj 11 0 obj <</ModDate(D:20200416183526+08'00')/CreationDate(D:20200416183526+08'00')/Producer(iText 2.1.7 by 1T3XT)/Title(��[���[�Thg\\~�)>> endobj xref 0 12 0000000000 65535 f 0000046407 00000 n 0000006627 00000 n 0000046281 00000 n 0000000015 00000 n 0000046663 00000 n
多个PDF文件或PDF数据流的合并
于 2020-04-16 18:50:25 首次发布