プログラマー必見!JavaでPDFファイルにバーコードを追加する完全ガイド

プログラマー必見!JavaでPDFファイルにバーコードを追加する完全ガイド 無料ツール
この記事は約34分で読めます。

作成・設定手順

Javaで処理を担当するプログラムを作成する

package com.rintech.filenamebarcode;

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.PDPageContentStream;
import org.apache.pdfbox.pdmodel.graphics.image.LosslessFactory;

import org.krysalis.barcode4j.impl.code128.Code128Bean;
import org.krysalis.barcode4j.output.bitmap.BitmapCanvasProvider;

import java.awt.image.BufferedImage;
import java.io.*;
import java.nio.file.*;
import java.nio.file.attribute.BasicFileAttributes;
import org.apache.pdfbox.pdmodel.graphics.image.PDImageXObject;

/**
 *
 * @author Hayashi_m
 */
public class FilenameBarcode {

    public static void main(String[] args) throws IOException {
        if (args.length != 1) {
            System.out.println("Usage: PdfBarcodeGenerator <directory>");
            System.exit(1);
        }

        String directoryPath = args[0];
        Files.walkFileTree(Paths.get(directoryPath), new SimpleFileVisitor<Path>() {
            @Override
            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                if (file.toString().toLowerCase().endsWith(".pdf")) {
                    System.out.println("Processing: " + file);
                    try {
                        generateBarcodeForPdf(file);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                return FileVisitResult.CONTINUE;
            }
        });
    }

    private static void generateBarcodeForPdf(Path pdfPath) throws IOException {
        // バーコードを生成
        Code128Bean barcodeBean = new Code128Bean();
        final int dpi = 150;

        // PDFファイルを読み込む
        try (PDDocument document = PDDocument.load(pdfPath.toFile())) {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            BitmapCanvasProvider canvas = new BitmapCanvasProvider(baos, "image/x-png", dpi, BufferedImage.TYPE_BYTE_BINARY, false, 0);

            // 拡張子を除去したファイル名でバーコードを生成
            String fileNameWithoutExt = pdfPath.getFileName().toString().replaceAll("\\.pdf$", "");
            barcodeBean.generateBarcode(canvas, fileNameWithoutExt);
            canvas.finish();

            ByteArrayInputStream barcodeInStream = new ByteArrayInputStream(baos.toByteArray());
            BufferedImage barcodeImage = javax.imageio.ImageIO.read(barcodeInStream);

            // 既存の最後のページを取得
            PDPage page = document.getPage(document.getNumberOfPages() - 1);
            PDPageContentStream contentStream = new PDPageContentStream(document, page, PDPageContentStream.AppendMode.APPEND, true);

            // バーコードをPDFに印字
            PDImageXObject barcodeXObject = LosslessFactory.createFromImage(document, barcodeImage);
            contentStream.drawImage(barcodeXObject, 150, 530, barcodeImage.getWidth() / 2, barcodeImage.getHeight() / 3);
            contentStream.close();

            // 同じファイル名でPDFを保存
            document.save(pdfPath.toString());
        }
    }
}

javaで画面を担当するプログラムを作成する

package com.rintech.filenamebarcode;

import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Hayashi_m
 */
public class FilenameBarcodeF extends javax.swing.JFrame {

    /**
     * Creates new form FilenameBarcodeF
     */
    public FilenameBarcodeF() {
        initComponents();
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        フォルダーFileChooser = new javax.swing.JFileChooser();
        ヘッターPanel = new javax.swing.JPanel();
        タイトルLabel = new javax.swing.JLabel();
        ディテールPanel = new javax.swing.JPanel();
        フォルダー指定Label = new javax.swing.JLabel();
        フォルダー指定TextField = new javax.swing.JTextField();
        フッターPanel = new javax.swing.JPanel();
        エラーTextField = new javax.swing.JTextField();
        終了Button = new javax.swing.JButton();
        処理Button = new javax.swing.JButton();

        フォルダーFileChooser.setCurrentDirectory(new java.io.File("D:\\運転日報\\新しいフォルダー"));
        フォルダーFileChooser.setFileSelectionMode(javax.swing.JFileChooser.DIRECTORIES_ONLY);

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setResizable(false);

        ヘッターPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder());

        タイトルLabel.setFont(new java.awt.Font("MT平成ゴシック体W5 JIS X 0208", 1, 36)); // NOI18N
        タイトルLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        タイトルLabel.setText("ファイル名をバーコードにするよ");
        タイトルLabel.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);

        javax.swing.GroupLayout ヘッターPanelLayout = new javax.swing.GroupLayout(ヘッターPanel);
        ヘッターPanel.setLayout(ヘッターPanelLayout);
        ヘッターPanelLayout.setHorizontalGroup(
            ヘッターPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(ヘッターPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(タイトルLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addContainerGap())
        );
        ヘッターPanelLayout.setVerticalGroup(
            ヘッターPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(ヘッターPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(タイトルLabel, javax.swing.GroupLayout.DEFAULT_SIZE, 65, Short.MAX_VALUE)
                .addContainerGap())
        );

        ディテールPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder());

        フォルダー指定Label.setFont(new java.awt.Font("MS Gothic", 0, 24)); // NOI18N
        フォルダー指定Label.setText("フォルダー");
        フォルダー指定Label.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED));

        フォルダー指定TextField.setFont(new java.awt.Font("MS Gothic", 0, 24)); // NOI18N
        フォルダー指定TextField.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mousePressed(java.awt.event.MouseEvent evt) {
                フォルダー指定TextFieldMousePressed(evt);
            }
        });

        javax.swing.GroupLayout ディテールPanelLayout = new javax.swing.GroupLayout(ディテールPanel);
        ディテールPanel.setLayout(ディテールPanelLayout);
        ディテールPanelLayout.setHorizontalGroup(
            ディテールPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(ディテールPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(フォルダー指定Label, javax.swing.GroupLayout.PREFERRED_SIZE, 129, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(フォルダー指定TextField)
                .addContainerGap())
        );
        ディテールPanelLayout.setVerticalGroup(
            ディテールPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(ディテールPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(ディテールPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(フォルダー指定Label, javax.swing.GroupLayout.PREFERRED_SIZE, 29, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(フォルダー指定TextField))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        フッターPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder());

        エラーTextField.setFont(new java.awt.Font("MS Gothic", 0, 18)); // NOI18N
        エラーTextField.setForeground(new java.awt.Color(255, 51, 51));
        エラーTextField.setBorder(null);
        エラーTextField.setEnabled(false);

        終了Button.setFont(new java.awt.Font("MS Gothic", 0, 24)); // NOI18N
        終了Button.setText("終了");
        終了Button.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED));
        終了Button.setPreferredSize(new java.awt.Dimension(80, 25));
        終了Button.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mousePressed(java.awt.event.MouseEvent evt) {
                終了ButtonMousePressed(evt);
            }
        });

        処理Button.setFont(new java.awt.Font("MS Gothic", 0, 24)); // NOI18N
        処理Button.setText("処理");
        処理Button.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED));
        処理Button.setPreferredSize(new java.awt.Dimension(80, 25));
        処理Button.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mousePressed(java.awt.event.MouseEvent evt) {
                処理ButtonMousePressed(evt);
            }
        });

        javax.swing.GroupLayout フッターPanelLayout = new javax.swing.GroupLayout(フッターPanel);
        フッターPanel.setLayout(フッターPanelLayout);
        フッターPanelLayout.setHorizontalGroup(
            フッターPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(フッターPanelLayout.createSequentialGroup()
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addComponent(エラーTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 534, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(処理Button, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(終了Button, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );
        フッターPanelLayout.setVerticalGroup(
            フッターPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(フッターPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(フッターPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                    .addComponent(処理Button, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 40, Short.MAX_VALUE)
                    .addComponent(終了Button, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(エラーTextField, javax.swing.GroupLayout.Alignment.LEADING))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(ヘッターPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addComponent(ディテールPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addComponent(フッターPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addComponent(ヘッターPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(ディテールPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(フッターPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void フォルダー指定TextFieldMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_フォルダー指定TextFieldMousePressed
        int returnVal = フォルダーFileChooser.showOpenDialog(this);
        if (returnVal == フォルダーFileChooser.APPROVE_OPTION) {
            File file = フォルダーFileChooser.getSelectedFile();
            this.フォルダー指定TextField.setText(file.getAbsolutePath());
        }
    }//GEN-LAST:event_フォルダー指定TextFieldMousePressed

    private void 終了ButtonMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_終了ButtonMousePressed
        System.exit(0); //終了
    }//GEN-LAST:event_終了ButtonMousePressed

    private void 処理ButtonMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_処理ButtonMousePressed
        //エラーチェック
        boolean errflg = false;

        if (this.フォルダー指定TextField.getText().trim().length() == 0) {
            this.エラーTextField.setText("PDFがあるフォルダーの場所が指定されていません。");
            errflg = true;
        }
        if (errflg == false) {
            String[] args = {this.フォルダー指定TextField.getText()};
            try {
                FilenameBarcode.main(args);
            } catch (IOException ex) {
                Logger.getLogger(FilenameBarcodeF.class.getName()).log(Level.SEVERE, null, ex);
            }
            System.exit(0); //終了};
        }
    }//GEN-LAST:event_処理ButtonMousePressed

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(FilenameBarcodeF.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(FilenameBarcodeF.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(FilenameBarcodeF.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(FilenameBarcodeF.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new FilenameBarcodeF().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JTextField エラーTextField;
    private javax.swing.JLabel タイトルLabel;
    private javax.swing.JPanel ディテールPanel;
    private javax.swing.JFileChooser フォルダーFileChooser;
    private javax.swing.JLabel フォルダー指定Label;
    private javax.swing.JTextField フォルダー指定TextField;
    private javax.swing.JPanel フッターPanel;
    private javax.swing.JPanel ヘッターPanel;
    private javax.swing.JButton 処理Button;
    private javax.swing.JButton 終了Button;
    // End of variables declaration//GEN-END:variables
}

Mavenのpom.xmlを作成する

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.rintech</groupId>
    <artifactId>FilenameBarcode</artifactId>
    <version>1.0</version>
    <packaging>jar</packaging>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <exec.mainClass>com.rintech.filenamebarcode.FilenameBarcodeF</exec.mainClass>
    </properties>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>3.1.0</version> 
                <configuration>
                    <archive>
                        <manifest>
                            <addClasspath>true</addClasspath>
                            <mainClass>com.rintech.filenamebarcode.FilenameBarcodeF</mainClass>
                        </manifest>
                    </archive>
                </configuration>
            </plugin>
            <plugin>
                <groupId>com.akathist.maven.plugins.launch4j</groupId>
                <artifactId>launch4j-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>launch4j</goal>
                        </goals>
                        <configuration>
                            <headerType>gui</headerType>
                            <jar>${project.build.directory}/FilenameBarcode-1.0.jar</jar>
                            <outfile>${project.build.directory}/FilenameBarcode.exe</outfile>
                            <icon>src/main/resources/barcode_scanner.ico</icon>
                        </configuration>
                    </execution>
                </executions>
            </plugin>         
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>3.1.0</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>java</goal>
                        </goals>
                        <configuration>
                            <mainClass>com.rintech.filenamebarcode.FilenameBarcodeF</mainClass>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
    <dependencies>
        <dependency>
            <groupId>org.apache.pdfbox</groupId>
            <artifactId>pdfbox</artifactId>
            <version>2.0.31</version>
        </dependency>
        <dependency>
            <groupId>net.sf.barcode4j</groupId>
            <artifactId>barcode4j</artifactId>
            <version>2.0</version>
        </dependency>
    </dependencies>
</project>

※使用する際は、自己責任でお願い致します。

最後に私からの宣伝

自分達でシステム構築できそうですか?

『専任の担当者がいないから無理かなぁ』
『担当者に構築する時間がないからなぁ』
『一人でやりきる自信がない』
『導入・構築までやってくれないかなぁ』

と色々と思う方もいたのではないでしょうか?

そんな方に朗報です。
御社が望む環境をお伝え頂き
環境構築・システム構築のお手伝いをさせて頂きます。
別途、メニューを設けておりますので、興味を持たれた方は
見積り希望と明記のうえお問い合わせ下さい
連絡お待ちしております。ここをクリック
※無理な場合もありますので、その際にはご理解の程宜しくお願い致します。

コメント

タイトルとURLをコピーしました