github.com/pdfcpu/pdfcpu@v0.11.1/pkg/api/create.go (about)

     1  /*
     2  	Copyright 2019 The pdfcpu Authors.
     3  
     4  	Licensed under the Apache License, Version 2.0 (the "License");
     5  	you may not use this file except in compliance with the License.
     6  	You may obtain a copy of the License at
     7  
     8  		http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  	Unless required by applicable law or agreed to in writing, software
    11  	distributed under the License is distributed on an "AS IS" BASIS,
    12  	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  	See the License for the specific language governing permissions and
    14  	limitations under the License.
    15  */
    16  
    17  package api
    18  
    19  import (
    20  	"io"
    21  	"os"
    22  
    23  	"github.com/pdfcpu/pdfcpu/pkg/log"
    24  	"github.com/pdfcpu/pdfcpu/pkg/pdfcpu"
    25  	"github.com/pdfcpu/pdfcpu/pkg/pdfcpu/create"
    26  	"github.com/pdfcpu/pdfcpu/pkg/pdfcpu/model"
    27  	"github.com/pdfcpu/pdfcpu/pkg/pdfcpu/types"
    28  	"github.com/pkg/errors"
    29  )
    30  
    31  // CreatePDFFile creates a PDF file for an xRefTable and writes it to outFile.
    32  func CreatePDFFile(xRefTable *model.XRefTable, outFile string, conf *model.Configuration) error {
    33  	f, err := os.Create(outFile)
    34  	if err != nil {
    35  		return err
    36  	}
    37  	defer f.Close()
    38  	ctx := pdfcpu.CreateContext(xRefTable, conf)
    39  	return WriteContext(ctx, f)
    40  }
    41  
    42  // Create renders the PDF structure represented by rs into w.
    43  // If rs is present, new PDF content will be appended including any empty pages needed.
    44  // rd is a JSON representation of PDF page content which may include form data.
    45  func Create(rs io.ReadSeeker, rd io.Reader, w io.Writer, conf *model.Configuration) error {
    46  	if rd == nil {
    47  		return errors.New("pdfcpu: Create: missing rd")
    48  	}
    49  
    50  	if conf == nil {
    51  		conf = model.NewDefaultConfiguration()
    52  	}
    53  	conf.Cmd = model.CREATE
    54  
    55  	var (
    56  		ctx *model.Context
    57  		err error
    58  	)
    59  
    60  	if rs != nil {
    61  		ctx, err = ReadValidateAndOptimize(rs, conf)
    62  	} else {
    63  		ctx, err = pdfcpu.CreateContextWithXRefTable(conf, types.PaperSize["A4"])
    64  	}
    65  	if err != nil {
    66  		return err
    67  	}
    68  
    69  	if err := create.FromJSON(ctx, rd); err != nil {
    70  		return err
    71  	}
    72  
    73  	if conf.PostProcessValidate {
    74  		if err = ValidateContext(ctx); err != nil {
    75  			return err
    76  		}
    77  	}
    78  
    79  	return WriteContext(ctx, w)
    80  }
    81  
    82  func handleOutFilePDF(inFilePDF, outFilePDF string, tmpFile *string) {
    83  	if outFilePDF != "" && inFilePDF != outFilePDF {
    84  		*tmpFile = outFilePDF
    85  		logWritingTo(outFilePDF)
    86  	} else {
    87  		logWritingTo(inFilePDF)
    88  	}
    89  }
    90  
    91  // CreateFile renders the PDF structure represented by inFileJSON into outFilePDF.
    92  // If inFilePDF is present, new PDF content will be appended including any empty pages needed.
    93  // inFileJSON represents PDF page content which may include form data.
    94  func CreateFile(inFilePDF, inFileJSON, outFilePDF string, conf *model.Configuration) (err error) {
    95  	var f0, f1, f2 *os.File
    96  
    97  	if f0, err = os.Open(inFileJSON); err != nil {
    98  		return err
    99  	}
   100  
   101  	rs := io.ReadSeeker(nil)
   102  	f1 = nil
   103  	if fileExists(inFilePDF) {
   104  		if f1, err = os.Open(inFilePDF); err != nil {
   105  			return err
   106  		}
   107  		log.CLI.Printf("reading %s...\n", inFilePDF)
   108  		rs = f1
   109  	}
   110  
   111  	tmpFile := inFilePDF + ".tmp"
   112  	handleOutFilePDF(inFilePDF, outFilePDF, &tmpFile)
   113  
   114  	if f2, err = os.Create(tmpFile); err != nil {
   115  		return err
   116  	}
   117  
   118  	defer func() {
   119  		if err != nil {
   120  			f2.Close()
   121  			if f1 != nil {
   122  				f1.Close()
   123  			}
   124  			f0.Close()
   125  			os.Remove(tmpFile)
   126  			return
   127  		}
   128  		if err = f2.Close(); err != nil {
   129  			return
   130  		}
   131  		if f1 != nil {
   132  			if err = f1.Close(); err != nil {
   133  				return
   134  			}
   135  		}
   136  		if err = f0.Close(); err != nil {
   137  			return
   138  		}
   139  		if outFilePDF == "" || inFilePDF == outFilePDF {
   140  			err = os.Rename(tmpFile, inFilePDF)
   141  		}
   142  	}()
   143  
   144  	return Create(rs, f0, f2, conf)
   145  }