[Java export PDF] Aspose-words export PDF guide: Java export template PDF with pictures (pro-test and practical)

Aspose-words export PDF guide: Java export template PDF with pictures

Hello everyone, long time no see. I’ve been busy recently, so I’ve been writing less and less blogs. During the development process, I encountered a need to export PDF, export according to the template style, and deal with image problems. I’m scratching my head. To be honest, I’ve been exposed to Excel export before. Wave this demand point uses Aspose.Words to export the pitfalls encountered in PDF export and how to export it.

Introduction to a Jar package

Aspose.Words is a commercial .NET class library that enables applications to handle large document tasks. Aspose.Words supports different formats such as Doc, Docx, PDF, etc. Using this class library can generate, modify, convert and print documents without using Microsoft.Word. Using Aspose.Words in a project can have the following benefits.
What I share today is to use Aspose.Words to export PDF and pictures in Java. The maven dependencies are as follows

        <dependency>
            <groupId>com.luhuiguo</groupId>
            <artifactId>aspose-words</artifactId>
            <version>23.1</version>
        </dependency>

Two export steps

Let's first take a look at the exported blank template
insert image description hereand observe this template. We can see that there are four places that need to be processed: realName, addr, picture 1, picture 2, and patrol check-in. First, execute to see the effect.
insert image description here

What we need to do is to save this template Word first, and then put it in our project. For example, I put it in the Resources directory here. Let’s gossip
insert image description here
and upload the code! !

    @ApiOperation("测试PDF导出")
    @GetMapping("/api/ffp/dict/PDFTest")
    public ApiResult<Boolean> PDFTest(HttpServletResponse response,@RequestParam Long id) throws Exception {
    
    
        FfpFileInfo fileInfo = ffpFileInfoService.getById(id);
        if (ObjectUtil.isEmpty(fileInfo)) {
    
    
            return ApiResult.error(602, "文件不存在");
        }
        String base64 = baseS3Service.downloadWithBase64(fileInfo.getFileKey());
        byte[] bytes = Base64.getDecoder().decode(base64);
        ClassPathResource  classPathResource= new ClassPathResource("/templateFile/demo.docx");
        InputStream inputStream = classPathResource.getInputStream();
        Document document=new Document(inputStream);
        Map paramsMap = new HashMap();
        paramsMap.put("realname","Spring不止春天");
        paramsMap.put("addr","四川");
        PdfUtils.replaceText(paramsMap,document);
        PdfUtils.replaceBookMarkImage( bytes,document);
        String name="测试测试";
        File tempFile = File.createTempFile(name, ".pdf");
        //插入表格
        DocumentBuilder builder = new DocumentBuilder(document);
        NodeCollection runs = document.getChildNodes(NodeType.PARAGRAPH, true);
        for (int i = 0; i < runs.getCount(); i++){
    
    
            Node node = runs.get(i);
            String text = node.getText();
            System.out.println(text);
            if (text.contains("巡防打卡")){
    
    
                builder.moveTo(node);
                Table table = builder.startTable();
                // Insert a cell
                builder.insertCell();
                table.autoFit( AutoFitBehavior.AUTO_FIT_TO_CONTENTS );
                table.setAlignment(1);
                builder.getCellFormat().setWidth(135);
                builder.write( "打卡时间" );
                builder.insertCell();
                builder.write( "日志" );
                builder.insertCell();
                builder.write( "打卡地址" );
                // End row
                builder.endRow();
                // start a next row and set its properties
                builder.getRowFormat().setHeight( 40 );
                builder.getCellFormat().setWidth(135);
                builder.insertCell();
                builder.write( "2023:09:01:" );
                builder.getCellFormat().setWrapText(true);
                builder.insertCell();
                builder.write( "进行了打卡的日志" );
                builder.getCellFormat().setWrapText(true);
                builder.insertCell();
                builder.write( "四川省成都市武侯区1111111111111111111" );
                builder.getCellFormat().setWrapText(true);
                builder.endRow();
                //第二行
                builder.insertCell();
                builder.write( "2023:09:01:" );
                builder.getCellFormat().setWrapText(true);
                builder.insertCell();
                builder.write( "进行了打卡的日志" );
                builder.getCellFormat().setWrapText(true);
                builder.insertCell();
                builder.write( "四川省成都市武侯区2222222222222222222222" );
                builder.getCellFormat().setWrapText(true);
                builder.endRow();
                // End table
                builder.endTable();

            }
        }
        document.save(new FileOutputStream(tempFile), SaveFormat.PDF);
        InputStream fis = new BufferedInputStream(new FileInputStream(tempFile));
        byte[] buffer = new byte[fis.available()];
        fis.read(buffer);
        fis.close();
        // 清空response
        response.reset();
        String filename=tempFile.getName();
        // 设置响应的头部信息
        response.setContentType("application/octet-stream;charset=UTF-8");
        String fileName = new String(filename.getBytes("gb2312"), "iso8859-1");
        response.setHeader("Content-disposition", "attachment;filename=" + fileName);
        OutputStream ouputStream = response.getOutputStream();
        ouputStream.write(buffer);
        ouputStream.flush();
        ouputStream.close();
        tempFile.delete();
        return ApiResult.success(true);
    }

Next, let me explain the PDF processing in three different formats, such as simple parameter replacement, image insertion, and list insertion.

A simple parameter substitution

The two parameters realName and addr belong to simple replacement values ​​for processing. You can see that there is such a section in the code
insert image description herethat replaceText is the real replacement method. The method is as follows:


    /***
     * 进行Word文件中的参数替换,方便转为PDF进行导出
     * @author jiazl
     * @date 2023/6/15 17:54
     * @param paramMap,doc
     * @return void
     **/
    public static void replaceText(Map<String, String> paramMap, Document doc) throws Exception {
    
    
        FindReplaceOptions opt = new FindReplaceOptions();
        for (Map.Entry<String, String> entry : paramMap.entrySet()) {
    
    
            String key = String.format("{%s}", entry.getKey());
            String value = Objects.isNull(entry.getValue()) ? "" : entry.getValue();
            doc.getRange().replace(key, value, opt);
        }
        int replace = doc.getRange().replace(Pattern.compile(PARAM_MATCH), "", opt);
        if (replace > 0) {
    
    
            logger.error("未知参数:{}", JSON.toJSONString(paramMap));
        }
    }

The meaning of this code is to find the {%s} parameter in Word, and use the Map of paramMap to replace the value. This is very simple and will not be described in detail.

Insertion of two pictures

Careful comrades have already discovered that the API I gave has parameters. What is this parameter? It is a file ID. To insert a picture at the place we want to insert, we need to find the node in Word. For example: the method of inserting a picture is
insert image description here:

    /***
     * 进行Word文件中的图片插入(单处地方,单个图片)
     * @author jiazl
     * @date 2023/6/15 17:54
     * @param doc
     * @return void
     **/
    public static void replaceBookMarkImage(  byte[] bytes, Document doc) throws Exception {
    
    
        DocumentBuilder db = new DocumentBuilder(doc);
        NodeCollection runs = doc.getChildNodes(NodeType.PARAGRAPH, true);
        for (int i = 0; i < runs.getCount(); i++) {
    
    
            Node node = runs.get(i);
            String text = node.getText();
            System.out.println(text);
            if (text.contains("图片1")) {
    
    
                db.moveTo(node);
                db.insertImage(bytes, 119.4, 64);
            }
        }
    }

insert image description hereIn the template pdf, it is here
insert image description herethat when he finds this node, it will execute

                db.moveTo(node);
                db.insertImage(bytes, 119.4, 64);

These two methods, the first is to transfer the operation object to this node, and the second is to insert the picture, 119.4 and 64 are the set picture size respectively.
(Of course, here is a Demo interface, so the node search picture 1 is hard-coded. You can pass in the node you want to find as a parameter, so that the code will be stronger!)

Insertion of three columns

My family, it’s too difficult. I have browsed many websites, and few people write clearly about list insertion, because this Jar package was repackaged by a domestic boss (genuine foreign charges), without comments, I tried it out one by one, please give me a thumbs up~~ For the operation of the list, we mainly look at this part of the
code

 //插入表格
        DocumentBuilder builder = new DocumentBuilder(document);
        NodeCollection runs = document.getChildNodes(NodeType.PARAGRAPH, true);
        for (int i = 0; i < runs.getCount(); i++){
    
    
            Node node = runs.get(i);
            String text = node.getText();
            System.out.println(text);
            if (text.contains("巡防打卡")){
    
    
                builder.moveTo(node);
                Table table = builder.startTable();
                // Insert a cell
                builder.insertCell();
                table.autoFit( AutoFitBehavior.AUTO_FIT_TO_CONTENTS );
                table.setAlignment(1);
                builder.getCellFormat().setWidth(135);
                builder.write( "打卡时间" );
                builder.insertCell();
                builder.write( "日志" );
                builder.insertCell();
                builder.write( "打卡地址" );
                // End row
                builder.endRow();
                // start a next row and set its properties
                builder.getRowFormat().setHeight( 40 );
                builder.getCellFormat().setWidth(135);
                builder.insertCell();
                builder.write( "2023:09:01:" );
                builder.getCellFormat().setWrapText(true);
                builder.insertCell();
                builder.write( "进行了打卡的日志" );
                builder.getCellFormat().setWrapText(true);
                builder.insertCell();
                builder.write( "四川省成都市武侯区1111111111111111111" );
                builder.getCellFormat().setWrapText(true);
                builder.endRow();
                //第二行
                builder.insertCell();
                builder.write( "2023:09:01:" );
                builder.getCellFormat().setWrapText(true);
                builder.insertCell();
                builder.write( "进行了打卡的日志" );
                builder.getCellFormat().setWrapText(true);
                builder.insertCell();
                builder.write( "四川省成都市武侯区2222222222222222222222" );
                builder.getCellFormat().setWrapText(true);
                builder.endRow();
                // End table
                builder.endTable();

            }
        }

Here, as a demo test interface, two rows of data are hard-coded, and when applied to specific businesses, you can use the for loop to insert.
insert image description hereIs this familiar? The insertion list is also to find the node that needs to be inserted, and then
insert image description herethe effect is like this. As
insert image description herefor the data insertion, please see:
insert image description herethe overall effect is as follows .
insert image description hereIt should be noted that sometimes some fields are too long

builder.getCellFormat().setWrapText(true);

This method in the code is to let him break the line in the box

Three summary and some points for attention

1 Because for bloggers, inserting pictures, inserting tables, and replacing template parameters are already enough to meet most of the development tasks. The deeper reason is that bloggers are lazy, so they don't understand it.
2 This Jar package has requirements for pictures, after some tests by bloggers. JPG, JPEG, and PNG can all export pictures, but if you criticize WEBP by name, you will report an error, because I am a lazy dog, and I have forgotten what I did wrong.
3 Adhere to the attitude of copying. If you have any questions about the methods in the blogger’s article, you can privately message the blogger. The blogger will reply when he sees it. Don’t worry, it’s not a big cake.
4 Some operations such as assigning values ​​to the response by the blogger at the end are useless. Swagger does not support exporting and downloading files. If you use PostMan to adjust the interface, you will find that
insert image description herethe blogger has worked hard and cannot solve the problem of the suffix, so the blogger put it badly and let the front end handle it.
5 Note that in the code

        Map paramsMap = new HashMap();
        paramsMap.put("realname","Spring不止春天");
        paramsMap.put("addr","四川");

This paramsMap should correspond to the PDF, otherwise an error will be reported, and any mistakes will be forgotten.
6 Some people will say, what about the word picture in the final effect? It's really smart, just replace it again, just replace the word "picture" with an empty string, because of the space, the code is not included.
7 Originally, I also wanted to write well, but I am really a lazy dog. I am sorry everyone, but I can guarantee that the code is good, it is used normally, and it is OK! If you have any questions, please feel free to contact~

Guess you like

Origin blog.csdn.net/weixin_49190101/article/details/131536093